瀏覽代碼

Parse fields in SELECT

main
Dylan Baker 4 年之前
父節點
當前提交
bb6fb86440
共有 1 個檔案被更改,包括 62 行新增5 行删除
  1. 62
    5
      src/parser.rs

+ 62
- 5
src/parser.rs 查看文件

1
-use std::slice::Iter;
1
+use std::{iter::Peekable, slice::Iter};
2
 
2
 
3
 use crate::error::ParserError;
3
 use crate::error::ParserError;
4
 use crate::token::{Token, TokenType};
4
 use crate::token::{Token, TokenType};
16
 
16
 
17
 #[derive(Debug, PartialEq)]
17
 #[derive(Debug, PartialEq)]
18
 pub enum Field {
18
 pub enum Field {
19
+    Named(String),
19
     Star,
20
     Star,
20
 }
21
 }
21
 
22
 
28
 }
29
 }
29
 
30
 
30
 pub fn parse(tokens: Vec<Token>) -> Result<Select, ParserError> {
31
 pub fn parse(tokens: Vec<Token>) -> Result<Select, ParserError> {
31
-    select_expression(&mut tokens.iter())
32
+    parse_select_expression(&mut tokens.iter().peekable())
32
 }
33
 }
33
 
34
 
34
-fn select_expression(tokens: &mut Iter<Token>) -> Result<Select, ParserError> {
35
+fn parse_select_expression(tokens: &mut Peekable<Iter<Token>>) -> Result<Select, ParserError> {
35
     eat(tokens, TokenType::Select)?;
36
     eat(tokens, TokenType::Select)?;
36
-    let fields = eat(tokens, TokenType::Star).and_then(|_| Ok(vec![Field::Star]))?;
37
+    let fields = parse_fields(tokens)?;
37
     eat(tokens, TokenType::From)?;
38
     eat(tokens, TokenType::From)?;
38
     let source = eat(tokens, TokenType::Identfiier).and_then(|t| Ok(Identifier::new(&t.value)))?;
39
     let source = eat(tokens, TokenType::Identfiier).and_then(|t| Ok(Identifier::new(&t.value)))?;
39
 
40
 
40
     Ok(Select { fields, source })
41
     Ok(Select { fields, source })
41
 }
42
 }
42
 
43
 
43
-fn eat<'a>(tokens: &'a mut Iter<Token>, token_type: TokenType) -> Result<&'a Token, ParserError> {
44
+fn parse_fields(tokens: &mut Peekable<Iter<Token>>) -> Result<Vec<Field>, ParserError> {
45
+    if current_token_is(tokens, TokenType::Star) {
46
+        eat(tokens, TokenType::Star).and_then(|_| Ok(vec![Field::Star]))
47
+    } else {
48
+        let mut fields: Vec<Field> = vec![];
49
+
50
+        loop {
51
+            let field = eat(tokens, TokenType::Identfiier)?;
52
+            fields.push(Field::Named(field.value.clone()));
53
+
54
+            if current_token_is(tokens, TokenType::Comma) {
55
+                eat(tokens, TokenType::Comma)?;
56
+            } else {
57
+                break;
58
+            }
59
+        }
60
+
61
+        Ok(fields)
62
+    }
63
+}
64
+
65
+fn current_token_is(tokens: &mut Peekable<Iter<Token>>, token_type: TokenType) -> bool {
66
+    match tokens.peek() {
67
+        Some(t) => t.token_type == token_type,
68
+        None => false,
69
+    }
70
+}
71
+
72
+fn eat<'a>(
73
+    tokens: &'a mut Peekable<Iter<Token>>,
74
+    token_type: TokenType,
75
+) -> Result<&'a Token, ParserError> {
44
     match tokens.next() {
76
     match tokens.next() {
45
         Some(token) => {
77
         Some(token) => {
46
             if token.token_type == token_type {
78
             if token.token_type == token_type {
76
             },
108
             },
77
         )
109
         )
78
     }
110
     }
111
+
112
+    #[test]
113
+    fn it_parses_a_select_with_field() {
114
+        assert_eq!(
115
+            _parse("SELECT field FROM index").unwrap(),
116
+            Select {
117
+                fields: vec![Field::Named("field".to_string())],
118
+                source: Identifier::new("index")
119
+            },
120
+        )
121
+    }
122
+
123
+    #[test]
124
+    fn it_parses_a_select_with_multiple_fields() {
125
+        assert_eq!(
126
+            _parse("SELECT field_one, field_two FROM index").unwrap(),
127
+            Select {
128
+                fields: vec![
129
+                    Field::Named("field_one".to_string()),
130
+                    Field::Named("field_two".to_string())
131
+                ],
132
+                source: Identifier::new("index")
133
+            },
134
+        )
135
+    }
79
 }
136
 }

Loading…
取消
儲存