helix_db/helixc/parser/
helix_parser.rs

1use super::{
2    location::{HasLoc, Loc},
3    parser_methods::ParserError,
4};
5use crate::protocol::value::Value;
6use chrono::{DateTime, NaiveDate, Utc};
7use pest::{
8    Parser as PestParser,
9    iterators::{Pair, Pairs},
10};
11use pest_derive::Parser;
12use serde::{Deserialize, Serialize};
13use std::{
14    collections::{HashMap, HashSet},
15    fmt::{Debug, Display},
16    io::Write,
17};
18
19#[derive(Parser)]
20#[grammar = "grammar.pest"]
21pub struct HelixParser {
22    source: Source,
23}
24
25pub struct Content {
26    pub content: String,
27    pub source: Source,
28    pub files: Vec<HxFile>,
29}
30
31#[derive(Clone, Serialize, Deserialize)]
32pub struct HxFile {
33    pub name: String,
34    pub content: String,
35}
36
37impl Default for HelixParser {
38    fn default() -> Self {
39        HelixParser {
40            source: Source {
41                source: String::new(),
42                node_schemas: Vec::new(),
43                edge_schemas: Vec::new(),
44                vector_schemas: Vec::new(),
45                queries: Vec::new(),
46            },
47        }
48    }
49}
50
51// AST Structures
52#[derive(Debug, Clone)]
53pub struct Source {
54    pub source: String,
55    pub node_schemas: Vec<NodeSchema>,
56    pub edge_schemas: Vec<EdgeSchema>,
57    pub vector_schemas: Vec<VectorSchema>,
58    pub queries: Vec<Query>,
59}
60
61impl Default for Source {
62    fn default() -> Self {
63        Source {
64            source: String::new(),
65            node_schemas: Vec::new(),
66            edge_schemas: Vec::new(),
67            vector_schemas: Vec::new(),
68            queries: Vec::new(),
69        }
70    }
71}
72#[derive(Debug, Clone)]
73pub struct NodeSchema {
74    pub name: (Loc, String),
75    pub fields: Vec<Field>,
76    pub loc: Loc,
77}
78
79#[derive(Debug, Clone)]
80pub struct VectorSchema {
81    pub name: String,
82    pub fields: Vec<Field>,
83    pub loc: Loc,
84}
85
86#[derive(Debug, Clone)]
87pub struct EdgeSchema {
88    pub name: (Loc, String),
89    pub from: (Loc, String),
90    pub to: (Loc, String),
91    pub properties: Option<Vec<Field>>,
92    pub loc: Loc,
93}
94
95#[derive(Debug, Clone)]
96pub struct Field {
97    pub prefix: FieldPrefix,
98    pub defaults: Option<DefaultValue>,
99    pub name: String,
100    pub field_type: FieldType,
101    pub loc: Loc,
102}
103impl Field {
104    pub fn is_indexed(&self) -> bool {
105        self.prefix.is_indexed()
106    }
107}
108
109#[derive(Debug, Clone)]
110pub enum DefaultValue {
111    Now,
112    String(String),
113    F32(f32),
114    F64(f64),
115    I8(i8),
116    I16(i16),
117    I32(i32),
118    I64(i64),
119    U8(u8),
120    U16(u16),
121    U32(u32),
122    U64(u64),
123    U128(u128),
124    Boolean(bool),
125    Empty,
126}
127
128#[derive(Debug, Clone)]
129pub enum FieldPrefix {
130    Index,
131    Optional,
132    Empty,
133}
134impl FieldPrefix {
135    pub fn is_indexed(&self) -> bool {
136        match self {
137            FieldPrefix::Index => true,
138            _ => false,
139        }
140    }
141}
142
143#[derive(Debug, Clone)]
144pub enum FieldType {
145    String,
146    F32,
147    F64,
148    I8,
149    I16,
150    I32,
151    I64,
152    U8,
153    U16,
154    U32,
155    U64,
156    U128,
157    Boolean,
158    Uuid,
159    Date,
160    Array(Box<FieldType>),
161    Identifier(String),
162    Object(HashMap<String, FieldType>),
163    // Closure(String, HashMap<String, FieldType>),
164}
165
166impl PartialEq for FieldType {
167    fn eq(&self, other: &Self) -> bool {
168        match (self, other) {
169            (FieldType::String, FieldType::String) => true,
170            (FieldType::F32 | FieldType::F64, FieldType::F32 | FieldType::F64) => true,
171            (
172                FieldType::I8
173                | FieldType::I16
174                | FieldType::I32
175                | FieldType::I64
176                | FieldType::U8
177                | FieldType::U16
178                | FieldType::U32
179                | FieldType::U64
180                | FieldType::U128,
181                FieldType::I8
182                | FieldType::I16
183                | FieldType::I32
184                | FieldType::I64
185                | FieldType::U8
186                | FieldType::U16
187                | FieldType::U32
188                | FieldType::U64
189                | FieldType::U128,
190            ) => true,
191
192            (FieldType::Boolean, FieldType::Boolean) => true,
193            (FieldType::Uuid, FieldType::Uuid) => true,
194            (FieldType::Date, FieldType::Date) => true,
195            (FieldType::Array(a), FieldType::Array(b)) => a == b,
196            (FieldType::Identifier(a), FieldType::Identifier(b)) => a == b,
197            (FieldType::Object(a), FieldType::Object(b)) => a == b,
198            // (FieldType::Closure(a, b), FieldType::Closure(c, d)) => a == c && b == d,
199            _ => false,
200        }
201    }
202}
203
204impl Display for FieldType {
205    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206        match self {
207            FieldType::String => write!(f, "String"),
208            FieldType::F32 => write!(f, "F32"),
209            FieldType::F64 => write!(f, "F64"),
210            FieldType::I8 => write!(f, "I8"),
211            FieldType::I16 => write!(f, "I16"),
212            FieldType::I32 => write!(f, "I32"),
213            FieldType::I64 => write!(f, "I64"),
214            FieldType::U8 => write!(f, "U8"),
215            FieldType::U16 => write!(f, "U16"),
216            FieldType::U32 => write!(f, "U32"),
217            FieldType::U64 => write!(f, "U64"),
218            FieldType::U128 => write!(f, "U128"),
219            FieldType::Boolean => write!(f, "Boolean"),
220            FieldType::Uuid => write!(f, "ID"),
221            FieldType::Date => write!(f, "Date"),
222            FieldType::Array(t) => write!(f, "Array({})", t),
223            FieldType::Identifier(s) => write!(f, "{}", s),
224            FieldType::Object(m) => {
225                write!(f, "{{")?;
226                for (k, v) in m {
227                    write!(f, "{}: {}", k, v)?;
228                }
229                write!(f, "}}")
230            } // FieldType::Closure(a, b) => write!(f, "Closure({})", a),
231        }
232    }
233}
234
235impl PartialEq<Value> for FieldType {
236    fn eq(&self, other: &Value) -> bool {
237        match (self, other) {
238            (FieldType::String, Value::String(_)) => true,
239            (FieldType::F32 | FieldType::F64, Value::F32(_) | Value::F64(_)) => true,
240            (
241                FieldType::I8
242                | FieldType::I16
243                | FieldType::I32
244                | FieldType::I64
245                | FieldType::U8
246                | FieldType::U16
247                | FieldType::U32
248                | FieldType::U64
249                | FieldType::U128,
250                Value::I8(_)
251                | Value::I16(_)
252                | Value::I32(_)
253                | Value::I64(_)
254                | Value::U8(_)
255                | Value::U16(_)
256                | Value::U32(_)
257                | Value::U64(_)
258                | Value::U128(_),
259            ) => true,
260            (FieldType::Boolean, Value::Boolean(_)) => true,
261            (FieldType::Array(inner_type), Value::Array(values)) => {
262                values.iter().all(|v| inner_type.as_ref().eq(v))
263            }
264            (FieldType::Object(fields), Value::Object(values)) => {
265                fields.len() == values.len()
266                    && fields.iter().all(|(k, field_type)| match values.get(k) {
267                        Some(value) => field_type.eq(value),
268                        None => false,
269                    })
270            }
271            (FieldType::Date, value) => match value {
272                Value::String(date) => {
273                    println!("date: {}, {:?}", date, date.parse::<NaiveDate>());
274                    date.parse::<NaiveDate>().is_ok() || date.parse::<DateTime<Utc>>().is_ok()
275                }
276                Value::I64(timestamp) => DateTime::from_timestamp(*timestamp, 0).is_some(),
277                Value::U64(timestamp) => DateTime::from_timestamp(*timestamp as i64, 0).is_some(),
278                _ => false,
279            },
280            l => {
281                println!("l: {:?}", l);
282                false
283            }
284        }
285    }
286}
287
288#[derive(Debug, Clone)]
289pub struct Query {
290    pub original_query: String,
291    pub is_mcp: bool,
292    pub name: String,
293    pub parameters: Vec<Parameter>,
294    pub statements: Vec<Statement>,
295    pub return_values: Vec<Expression>,
296    pub loc: Loc,
297}
298
299#[derive(Debug, Clone)]
300pub struct Parameter {
301    pub name: (Loc, String),
302    pub param_type: (Loc, FieldType),
303    pub loc: Loc,
304}
305
306#[derive(Debug, Clone)]
307pub struct Statement {
308    pub loc: Loc,
309    pub statement: StatementType,
310}
311
312#[derive(Debug, Clone)]
313pub enum StatementType {
314    Assignment(Assignment),
315    AddVector(AddVector),
316    AddNode(AddNode),
317    AddEdge(AddEdge),
318    Drop(Expression),
319    SearchVector(SearchVector),
320    BatchAddVector(BatchAddVector),
321    BM25Search(BM25Search),
322    ForLoop(ForLoop),
323}
324
325#[derive(Debug, Clone)]
326pub struct Assignment {
327    pub variable: String,
328    pub value: Expression,
329    pub loc: Loc,
330}
331
332#[derive(Debug, Clone)]
333pub struct ForLoop {
334    pub variable: ForLoopVars,
335    pub in_variable: (Loc, String),
336    pub statements: Vec<Statement>,
337    pub loc: Loc,
338}
339
340#[derive(Debug, Clone)]
341pub enum ForLoopVars {
342    Identifier {
343        name: String,
344        loc: Loc,
345    },
346    ObjectAccess {
347        name: String,
348        field: String,
349        loc: Loc,
350    },
351    ObjectDestructuring {
352        fields: Vec<(Loc, String)>,
353        loc: Loc,
354    },
355}
356
357#[derive(Debug, Clone)]
358pub struct Expression {
359    pub loc: Loc,
360    pub expr: ExpressionType,
361}
362
363#[derive(Debug, Clone)]
364pub enum ExpressionType {
365    Traversal(Box<Traversal>),
366    Identifier(String),
367    StringLiteral(String),
368    IntegerLiteral(i32),
369    FloatLiteral(f64),
370    BooleanLiteral(bool),
371    Exists(Box<Expression>),
372    BatchAddVector(BatchAddVector),
373    AddVector(AddVector),
374    AddNode(AddNode),
375    AddEdge(AddEdge),
376    And(Vec<Expression>),
377    Or(Vec<Expression>),
378    SearchVector(SearchVector),
379    BM25Search(BM25Search),
380    Empty,
381}
382
383#[derive(Debug, Clone)]
384pub struct Traversal {
385    pub start: StartNode,
386    pub steps: Vec<Step>,
387    pub loc: Loc,
388}
389
390#[derive(Debug, Clone)]
391pub struct BatchAddVector {
392    pub vector_type: Option<String>,
393    pub vec_identifier: Option<String>,
394    pub fields: Option<HashMap<String, ValueType>>,
395    pub loc: Loc,
396}
397
398#[derive(Debug, Clone)]
399pub enum StartNode {
400    Node {
401        node_type: String,
402        ids: Option<Vec<IdType>>,
403    },
404    Edge {
405        edge_type: String,
406        ids: Option<Vec<IdType>>,
407    },
408    Identifier(String),
409    Anonymous,
410}
411
412#[derive(Debug, Clone)]
413pub struct Step {
414    pub loc: Loc,
415    pub step: StepType,
416}
417
418#[derive(Debug, Clone)]
419pub enum StepType {
420    Node(GraphStep),
421    Edge(GraphStep),
422    Where(Box<Expression>),
423    BooleanOperation(BooleanOp),
424    Count,
425    Update(Update),
426    Object(Object),
427    Exclude(Exclude),
428    Closure(Closure),
429    Range((Expression, Expression)),
430    OrderByAsc(Box<Expression>),
431    OrderByDesc(Box<Expression>),
432    AddEdge(AddEdge),
433}
434impl PartialEq<StepType> for StepType {
435    fn eq(&self, other: &StepType) -> bool {
436        match (self, other) {
437            (&StepType::Node(_), &StepType::Node(_)) => true,
438            (&StepType::Edge(_), &StepType::Edge(_)) => true,
439            (&StepType::Where(_), &StepType::Where(_)) => true,
440            (&StepType::BooleanOperation(_), &StepType::BooleanOperation(_)) => true,
441            (&StepType::Count, &StepType::Count) => true,
442            (&StepType::Update(_), &StepType::Update(_)) => true,
443            (&StepType::Object(_), &StepType::Object(_)) => true,
444            (&StepType::Exclude(_), &StepType::Exclude(_)) => true,
445            (&StepType::Closure(_), &StepType::Closure(_)) => true,
446            (&StepType::Range(_), &StepType::Range(_)) => true,
447            (&StepType::OrderByAsc(_), &StepType::OrderByAsc(_)) => true,
448            (&StepType::OrderByDesc(_), &StepType::OrderByDesc(_)) => true,
449            (&StepType::AddEdge(_), &StepType::AddEdge(_)) => true,
450            _ => false,
451        }
452    }
453}
454#[derive(Debug, Clone)]
455pub struct FieldAddition {
456    pub key: String,
457    pub value: FieldValue,
458    pub loc: Loc,
459}
460
461#[derive(Debug, Clone)]
462pub struct FieldValue {
463    pub loc: Loc,
464    pub value: FieldValueType,
465}
466
467#[derive(Debug, Clone)]
468pub enum FieldValueType {
469    Traversal(Box<Traversal>),
470    Expression(Expression),
471    Fields(Vec<FieldAddition>),
472    Literal(Value),
473    Identifier(String),
474    Empty,
475}
476
477#[derive(Debug, Clone)]
478pub struct GraphStep {
479    pub loc: Loc,
480    pub step: GraphStepType,
481}
482
483#[derive(Debug, Clone)]
484pub enum GraphStepType {
485    Out(String),
486    In(String),
487
488    FromN,
489    ToN,
490    FromV,
491    ToV,
492
493    OutE(String),
494    InE(String),
495
496    ShortestPath(ShortestPath),
497    SearchVector(SearchVector),
498}
499impl GraphStep {
500    pub fn get_item_type(&self) -> Option<String> {
501        match &self.step {
502            GraphStepType::Out(s) => Some(s.clone()),
503            GraphStepType::In(s) => Some(s.clone()),
504            GraphStepType::OutE(s) => Some(s.clone()),
505            GraphStepType::InE(s) => Some(s.clone()),
506            GraphStepType::SearchVector(s) => Some(s.vector_type.clone().unwrap()),
507            _ => None,
508        }
509    }
510}
511
512#[derive(Debug, Clone)]
513pub struct ShortestPath {
514    pub loc: Loc,
515    pub from: Option<IdType>,
516    pub to: Option<IdType>,
517    pub type_arg: Option<String>,
518}
519
520#[derive(Debug, Clone)]
521pub struct BooleanOp {
522    pub loc: Loc,
523    pub op: BooleanOpType,
524}
525
526#[derive(Debug, Clone)]
527pub enum BooleanOpType {
528    And(Vec<Expression>),
529    Or(Vec<Expression>),
530    GreaterThan(Box<Expression>),
531    GreaterThanOrEqual(Box<Expression>),
532    LessThan(Box<Expression>),
533    LessThanOrEqual(Box<Expression>),
534    Equal(Box<Expression>),
535    NotEqual(Box<Expression>),
536}
537
538#[derive(Debug, Clone)]
539pub enum VectorData {
540    Vector(Vec<f64>),
541    Identifier(String),
542    Embed(Embed),
543}
544
545#[derive(Debug, Clone)]
546pub struct Embed {
547    pub loc: Loc,
548    pub value: EvaluatesToString,
549}
550
551#[derive(Debug, Clone)]
552pub enum EvaluatesToString {
553    Identifier(String),
554    StringLiteral(String),
555}
556
557#[derive(Debug, Clone)]
558pub struct SearchVector {
559    pub loc: Loc,
560    pub vector_type: Option<String>,
561    pub data: Option<VectorData>,
562    pub k: Option<EvaluatesToNumber>,
563    pub pre_filter: Option<Box<Expression>>,
564}
565
566#[derive(Debug, Clone)]
567pub struct BM25Search {
568    pub loc: Loc,
569    pub type_arg: Option<String>,
570    pub data: Option<ValueType>,
571    pub k: Option<EvaluatesToNumber>,
572}
573
574#[derive(Debug, Clone)]
575pub struct EvaluatesToNumber {
576    pub loc: Loc,
577    pub value: EvaluatesToNumberType,
578}
579
580#[derive(Debug, Clone)]
581pub enum EvaluatesToNumberType {
582    I8(i8),
583    I16(i16),
584    I32(i32),
585    I64(i64),
586    U8(u8),
587    U16(u16),
588    U32(u32),
589    U64(u64),
590    U128(u128),
591    F32(f32),
592    F64(f64),
593    Identifier(String),
594}
595
596#[derive(Debug, Clone)]
597pub struct AddVector {
598    pub loc: Loc,
599    pub vector_type: Option<String>,
600    pub data: Option<VectorData>,
601    pub fields: Option<HashMap<String, ValueType>>,
602}
603
604#[derive(Debug, Clone)]
605pub struct AddNode {
606    pub loc: Loc,
607    pub node_type: Option<String>,
608    pub fields: Option<HashMap<String, ValueType>>,
609}
610
611#[derive(Debug, Clone)]
612pub struct AddEdge {
613    pub loc: Loc,
614    pub edge_type: Option<String>,
615    pub fields: Option<HashMap<String, ValueType>>,
616    pub connection: EdgeConnection,
617    pub from_identifier: bool,
618}
619
620#[derive(Debug, Clone)]
621pub struct EdgeConnection {
622    pub loc: Loc,
623    pub from_id: Option<IdType>,
624    pub to_id: Option<IdType>,
625}
626
627#[derive(Debug, Clone)]
628pub enum IdType {
629    Literal {
630        value: String,
631        loc: Loc,
632    },
633    Identifier {
634        value: String,
635        loc: Loc,
636    },
637    ByIndex {
638        index: Box<IdType>,
639        value: Box<ValueType>,
640        loc: Loc,
641    },
642}
643impl Display for IdType {
644    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
645        match self {
646            IdType::Literal { value, loc: _ } => write!(f, "{}", value),
647            IdType::Identifier { value, loc: _ } => write!(f, "{}", value),
648            IdType::ByIndex {
649                index,
650                value: _,
651                loc: _,
652            } => write!(f, "{}", index),
653        }
654    }
655}
656
657#[derive(Debug, Clone)]
658pub enum ValueType {
659    Literal {
660        value: Value,
661        loc: Loc,
662    },
663    Identifier {
664        value: String,
665        loc: Loc,
666    },
667    Object {
668        fields: HashMap<String, ValueType>,
669        loc: Loc,
670    },
671}
672impl ValueType {
673    pub fn new(value: Value, loc: Loc) -> ValueType {
674        ValueType::Literal { value, loc }
675    }
676}
677
678impl From<Value> for ValueType {
679    fn from(value: Value) -> ValueType {
680        match value {
681            Value::String(s) => ValueType::Literal {
682                value: Value::String(s),
683                loc: Loc::empty(),
684            },
685            Value::I32(i) => ValueType::Literal {
686                value: Value::I32(i),
687                loc: Loc::empty(),
688            },
689            Value::F64(f) => ValueType::Literal {
690                value: Value::F64(f),
691                loc: Loc::empty(),
692            },
693            Value::Boolean(b) => ValueType::Literal {
694                value: Value::Boolean(b),
695                loc: Loc::empty(),
696            },
697            Value::Array(arr) => ValueType::Literal {
698                value: Value::Array(arr),
699                loc: Loc::empty(),
700            },
701            Value::Empty => ValueType::Literal {
702                value: Value::Empty,
703                loc: Loc::empty(),
704            },
705            _ => unreachable!(),
706        }
707    }
708}
709
710impl From<IdType> for String {
711    fn from(id_type: IdType) -> String {
712        match id_type {
713            IdType::Literal { mut value, loc: _ } => {
714                value.retain(|c| c != '"');
715                value
716            }
717            IdType::Identifier { value, loc: _ } => value,
718            IdType::ByIndex {
719                index,
720                value: _,
721                loc: _,
722            } => String::from(*index),
723        }
724    }
725}
726
727impl From<String> for IdType {
728    fn from(mut s: String) -> IdType {
729        s.retain(|c| c != '"');
730        IdType::Literal {
731            value: s,
732            loc: Loc::empty(),
733        }
734    }
735}
736
737#[derive(Debug, Clone)]
738pub struct Update {
739    pub fields: Vec<FieldAddition>,
740    pub loc: Loc,
741}
742
743#[derive(Debug, Clone)]
744pub struct Object {
745    pub loc: Loc,
746    // TODO: Change this to be a vec of structs where the enums holds the name and value
747    pub fields: Vec<FieldAddition>,
748    pub should_spread: bool,
749}
750
751#[derive(Debug, Clone)]
752pub struct Exclude {
753    pub fields: Vec<(Loc, String)>,
754    pub loc: Loc,
755}
756
757#[derive(Debug, Clone)]
758pub struct Closure {
759    pub identifier: String,
760    pub object: Object,
761    pub loc: Loc,
762}
763
764impl HelixParser {
765    pub fn parse_source(input: &Content) -> Result<Source, ParserError> {
766        let mut source = Source {
767            source: String::new(),
768            node_schemas: Vec::new(),
769            edge_schemas: Vec::new(),
770            vector_schemas: Vec::new(),
771            queries: Vec::new(),
772        };
773
774        input.files.iter().try_for_each(|file| {
775            source.source.push_str(&file.content);
776            source.source.push_str("\n");
777            let pair = match HelixParser::parse(Rule::source, &file.content) {
778                Ok(mut pairs) => {
779                    let pair = pairs
780                        .next()
781                        .ok_or_else(|| ParserError::from("Empty input"))?;
782                    pair
783                }
784                Err(e) => {
785                    return Err(ParserError::from(e));
786                }
787            };
788            let mut parser = HelixParser {
789                source: Source::default(),
790            };
791
792            let pairs = pair.into_inner();
793            let mut remaining = HashSet::new();
794            for pair in pairs {
795                match pair.as_rule() {
796                    Rule::node_def => {
797                        let node_schema = parser.parse_node_def(pair, file.name.clone())?;
798                        parser.source.node_schemas.push(node_schema);
799                    }
800                    Rule::edge_def => {
801                        let edge_schema = parser.parse_edge_def(pair, file.name.clone())?;
802                        parser.source.edge_schemas.push(edge_schema);
803                    }
804                    Rule::vector_def => {
805                        let vector_schema = parser.parse_vector_def(pair, file.name.clone())?;
806                        parser.source.vector_schemas.push(vector_schema);
807                    }
808                    Rule::query_def => {
809                        // parser.source.queries.push(parser.parse_query_def(pairs.next().unwrap())?),
810                        remaining.insert(pair);
811                    }
812                    Rule::EOI => (),
813                    _ => return Err(ParserError::from("Unexpected rule encountered")),
814                }
815            }
816
817            for pair in remaining {
818                // println!("{:?}", parser.source);
819                parser
820                    .source
821                    .queries
822                    .push(parser.parse_query_def(pair, file.name.clone())?);
823            }
824
825            // parse all schemas first then parse queries using self
826            source.node_schemas.extend(parser.source.node_schemas);
827            source.edge_schemas.extend(parser.source.edge_schemas);
828            source.vector_schemas.extend(parser.source.vector_schemas);
829            source.queries.extend(parser.source.queries);
830            Ok(())
831        })?;
832
833        Ok(source)
834    }
835
836    fn parse_node_def(
837        &self,
838        pair: Pair<Rule>,
839        filepath: String,
840    ) -> Result<NodeSchema, ParserError> {
841        let mut pairs = pair.clone().into_inner();
842        let name = pairs.next().unwrap().as_str().to_string();
843        let fields = self.parse_node_body(pairs.next().unwrap())?;
844        Ok(NodeSchema {
845            name: (pair.loc(), name),
846            fields,
847            loc: pair.loc_with_filepath(filepath),
848        })
849    }
850
851    fn parse_vector_def(
852        &self,
853        pair: Pair<Rule>,
854        filepath: String,
855    ) -> Result<VectorSchema, ParserError> {
856        let mut pairs = pair.clone().into_inner();
857        let name = pairs.next().unwrap().as_str().to_string();
858        let fields = self.parse_node_body(pairs.next().unwrap())?;
859        Ok(VectorSchema {
860            name,
861            fields,
862            loc: pair.loc_with_filepath(filepath),
863        })
864    }
865
866    fn parse_node_body(&self, pair: Pair<Rule>) -> Result<Vec<Field>, ParserError> {
867        let field_defs = pair
868            .into_inner()
869            .find(|p| p.as_rule() == Rule::field_defs)
870            .expect("Expected field_defs in properties");
871
872        // Now parse each individual field_def
873        field_defs
874            .into_inner()
875            .map(|p| self.parse_field_def(p))
876            .collect::<Result<Vec<_>, _>>()
877    }
878
879    fn parse_field_type(
880        &self,
881        field: Pair<Rule>,
882        schema: Option<&Source>,
883    ) -> Result<FieldType, ParserError> {
884        match field.as_rule() {
885            Rule::named_type => {
886                let type_str = field.as_str();
887                match type_str {
888                    "String" => Ok(FieldType::String),
889                    "Boolean" => Ok(FieldType::Boolean),
890                    "F32" => Ok(FieldType::F32),
891                    "F64" => Ok(FieldType::F64),
892                    "I8" => Ok(FieldType::I8),
893                    "I16" => Ok(FieldType::I16),
894                    "I32" => Ok(FieldType::I32),
895                    "I64" => Ok(FieldType::I64),
896                    "U8" => Ok(FieldType::U8),
897                    "U16" => Ok(FieldType::U16),
898                    "U32" => Ok(FieldType::U32),
899                    "U64" => Ok(FieldType::U64),
900                    "U128" => Ok(FieldType::U128),
901                    _ => unreachable!(),
902                }
903            }
904            Rule::array => {
905                return Ok(FieldType::Array(Box::new(
906                    self.parse_field_type(
907                        // unwraps the array type because grammar type is
908                        // { array { param_type { array | object | named_type } } }
909                        field
910                            .into_inner()
911                            .next()
912                            .unwrap()
913                            .into_inner()
914                            .next()
915                            .unwrap(),
916                        schema,
917                    )?,
918                )));
919            }
920            Rule::object => {
921                let mut fields = HashMap::new();
922                for field in field.into_inner().next().unwrap().into_inner() {
923                    let (field_name, field_type) = {
924                        let mut field_pair = field.clone().into_inner();
925                        (
926                            field_pair.next().unwrap().as_str().to_string(),
927                            field_pair.next().unwrap().into_inner().next().unwrap(),
928                        )
929                    };
930                    let field_type = self.parse_field_type(field_type, Some(&self.source))?;
931                    fields.insert(field_name, field_type);
932                }
933                Ok(FieldType::Object(fields))
934            }
935            Rule::identifier => Ok(FieldType::Identifier(field.as_str().to_string())),
936            Rule::ID_TYPE => Ok(FieldType::Uuid),
937            Rule::date_type => Ok(FieldType::Date),
938            _ => {
939                unreachable!()
940            }
941        }
942    }
943
944    fn parse_field_def(&self, pair: Pair<Rule>) -> Result<Field, ParserError> {
945        let mut pairs = pair.clone().into_inner();
946        // structure is index? ~ identifier ~ ":" ~ param_type
947        let prefix: FieldPrefix = match pairs.clone().next().unwrap().as_rule() {
948            Rule::index => {
949                pairs.next().unwrap();
950                FieldPrefix::Index
951            }
952            // Rule::optional => {
953            //     pairs.next().unwrap();
954            //     FieldPrefix::Optional
955            // }
956            _ => FieldPrefix::Empty,
957        };
958        let name = pairs.next().unwrap().as_str().to_string();
959
960        let field_type = self.parse_field_type(
961            pairs.next().unwrap().into_inner().next().unwrap(),
962            Some(&self.source),
963        )?;
964
965        let defaults = match pairs.next() {
966            Some(pair) => {
967                if pair.as_rule() == Rule::default {
968                    let default_value = match pair.into_inner().next() {
969                        Some(pair) => match pair.as_rule() {
970                            Rule::string_literal => DefaultValue::String(pair.as_str().to_string()),
971                            Rule::float => {
972                                match field_type {
973                                    FieldType::F32 => {
974                                        DefaultValue::F32(pair.as_str().parse::<f32>().unwrap())
975                                    }
976                                    FieldType::F64 => {
977                                        DefaultValue::F64(pair.as_str().parse::<f64>().unwrap())
978                                    }
979                                    _ => unreachable!(), // throw error
980                                }
981                            }
982                            Rule::integer => {
983                                match field_type {
984                                    FieldType::I8 => {
985                                        DefaultValue::I8(pair.as_str().parse::<i8>().unwrap())
986                                    }
987                                    FieldType::I16 => {
988                                        DefaultValue::I16(pair.as_str().parse::<i16>().unwrap())
989                                    }
990                                    FieldType::I32 => {
991                                        DefaultValue::I32(pair.as_str().parse::<i32>().unwrap())
992                                    }
993                                    FieldType::I64 => {
994                                        DefaultValue::I64(pair.as_str().parse::<i64>().unwrap())
995                                    }
996                                    FieldType::U8 => {
997                                        DefaultValue::U8(pair.as_str().parse::<u8>().unwrap())
998                                    }
999                                    FieldType::U16 => {
1000                                        DefaultValue::U16(pair.as_str().parse::<u16>().unwrap())
1001                                    }
1002                                    FieldType::U32 => {
1003                                        DefaultValue::U32(pair.as_str().parse::<u32>().unwrap())
1004                                    }
1005                                    FieldType::U64 => {
1006                                        DefaultValue::U64(pair.as_str().parse::<u64>().unwrap())
1007                                    }
1008                                    FieldType::U128 => {
1009                                        DefaultValue::U128(pair.as_str().parse::<u128>().unwrap())
1010                                    }
1011                                    _ => unreachable!(), // throw error
1012                                }
1013                            }
1014                            Rule::now => DefaultValue::Now,
1015                            Rule::boolean => {
1016                                DefaultValue::Boolean(pair.as_str().parse::<bool>().unwrap())
1017                            }
1018                            _ => unreachable!(), // throw error
1019                        },
1020                        None => DefaultValue::Empty,
1021                    };
1022                    Some(default_value)
1023                } else {
1024                    None
1025                }
1026            }
1027            None => None,
1028        };
1029
1030        Ok(Field {
1031            prefix,
1032            defaults,
1033            name,
1034            field_type,
1035            loc: pair.loc(),
1036        })
1037    }
1038
1039    fn parse_edge_def(
1040        &self,
1041        pair: Pair<Rule>,
1042        filepath: String,
1043    ) -> Result<EdgeSchema, ParserError> {
1044        let mut pairs = pair.clone().into_inner();
1045        let name = pairs.next().unwrap().as_str().to_string();
1046        let body = pairs.next().unwrap();
1047        let mut body_pairs = body.into_inner();
1048
1049        let from = {
1050            let pair = body_pairs.next().unwrap();
1051            (pair.loc(), pair.as_str().to_string())
1052        };
1053        let to = {
1054            let pair = body_pairs.next().unwrap();
1055            (pair.loc(), pair.as_str().to_string())
1056        };
1057        let properties = match body_pairs.next() {
1058            Some(pair) => Some(self.parse_properties(pair)?),
1059            None => None,
1060        };
1061
1062        Ok(EdgeSchema {
1063            name: (pair.loc(), name),
1064            from,
1065            to,
1066            properties,
1067            loc: pair.loc_with_filepath(filepath),
1068        })
1069    }
1070    fn parse_properties(&self, pair: Pair<Rule>) -> Result<Vec<Field>, ParserError> {
1071        pair.into_inner()
1072            .find(|p| p.as_rule() == Rule::field_defs)
1073            .map_or(Ok(Vec::new()), |field_defs| {
1074                field_defs
1075                    .into_inner()
1076                    .map(|p| self.parse_field_def(p))
1077                    .collect::<Result<Vec<_>, _>>()
1078            })
1079    }
1080
1081    fn parse_query_def(&self, pair: Pair<Rule>, filepath: String) -> Result<Query, ParserError> {
1082        let original_query = pair.clone().as_str().to_string();
1083        let mut pairs = pair.clone().into_inner();
1084        let is_mcp = match pairs.peek() {
1085            Some(pair) if pair.as_rule() == Rule::mcp_macro => {
1086                pairs.next();
1087                true
1088            }
1089            _ => false,
1090        };
1091        let name = pairs.next().unwrap().as_str().to_string();
1092        let parameters = self.parse_parameters(pairs.next().unwrap())?;
1093        let nect = pairs.next().unwrap();
1094        let statements = self.parse_query_body(nect)?;
1095        let return_values = self.parse_return_statement(pairs.next().unwrap())?;
1096
1097        Ok(Query {
1098            is_mcp,
1099            name,
1100            parameters,
1101            statements,
1102            return_values,
1103            original_query,
1104            loc: pair.loc_with_filepath(filepath),
1105        })
1106    }
1107
1108    fn parse_parameters(&self, pair: Pair<Rule>) -> Result<Vec<Parameter>, ParserError> {
1109        let mut seen = HashSet::new();
1110        pair.clone()
1111            .into_inner()
1112            .map(|p: Pair<'_, Rule>| -> Result<Parameter, ParserError> {
1113                let mut inner = p.into_inner();
1114                let name = {
1115                    let pair = inner.next().unwrap();
1116                    (pair.loc(), pair.as_str().to_string())
1117                };
1118
1119                // gets param type
1120                let param_pair = inner
1121                    .clone()
1122                    .next()
1123                    .unwrap()
1124                    .clone()
1125                    .into_inner()
1126                    .next()
1127                    .unwrap();
1128                let param_type_location = param_pair.loc();
1129                let param_type = self.parse_field_type(
1130                    // unwraps the param type to get the rule (array, object, named_type, etc)
1131                    param_pair,
1132                    Some(&self.source),
1133                )?;
1134
1135                if seen.insert(name.1.clone()) {
1136                    Ok(Parameter {
1137                        name,
1138                        param_type: (param_type_location, param_type),
1139                        loc: pair.loc(),
1140                    })
1141                } else {
1142                    Err(ParserError::from(format!(
1143                        r#"Duplicate parameter name: {}
1144                            Please use unique parameter names.
1145
1146                            Error happened at line {} column {} here: {}
1147                        "#,
1148                        name.1,
1149                        pair.line_col().0,
1150                        pair.line_col().1,
1151                        pair.as_str(),
1152                    )))
1153                }
1154            })
1155            .collect::<Result<Vec<_>, _>>()
1156    }
1157
1158    fn parse_query_body(&self, pair: Pair<Rule>) -> Result<Vec<Statement>, ParserError> {
1159        pair.into_inner()
1160            .map(|p| match p.as_rule() {
1161                Rule::get_stmt => Ok(Statement {
1162                    loc: p.loc(),
1163                    statement: StatementType::Assignment(self.parse_get_statement(p)?),
1164                }),
1165                Rule::AddN => Ok(Statement {
1166                    loc: p.loc(),
1167                    statement: StatementType::AddNode(self.parse_add_node(p)?),
1168                }),
1169                Rule::AddV => Ok(Statement {
1170                    loc: p.loc(),
1171                    statement: StatementType::AddVector(self.parse_add_vector(p)?),
1172                }),
1173                Rule::AddE => Ok(Statement {
1174                    loc: p.loc(),
1175                    statement: StatementType::AddEdge(self.parse_add_edge(p, false)?),
1176                }),
1177                Rule::drop => Ok(Statement {
1178                    loc: p.loc(),
1179                    statement: StatementType::Drop(self.parse_expression(p)?),
1180                }),
1181                Rule::BatchAddV => Ok(Statement {
1182                    loc: p.loc(),
1183                    statement: StatementType::BatchAddVector(self.parse_batch_add_vector(p)?),
1184                }),
1185                Rule::search_vector => Ok(Statement {
1186                    loc: p.loc(),
1187                    statement: StatementType::SearchVector(self.parse_search_vector(p)?),
1188                }),
1189                Rule::bm25_search => Ok(Statement {
1190                    loc: p.loc(),
1191                    statement: StatementType::BM25Search(self.parse_bm25_search(p)?),
1192                }),
1193                Rule::for_loop => Ok(Statement {
1194                    loc: p.loc(),
1195                    statement: StatementType::ForLoop(self.parse_for_loop(p)?),
1196                }),
1197                _ => Err(ParserError::from(format!(
1198                    "Unexpected statement type in query body: {:?}",
1199                    p.as_rule()
1200                ))),
1201            })
1202            .collect()
1203    }
1204
1205    fn parse_bm25_search(&self, pair: Pair<Rule>) -> Result<BM25Search, ParserError> {
1206        let mut pairs = pair.clone().into_inner();
1207        let vector_type = pairs.next().unwrap().as_str().to_string();
1208        let query = match pairs.next() {
1209            Some(pair) => match pair.as_rule() {
1210                Rule::identifier => ValueType::Identifier {
1211                    value: pair.as_str().to_string(),
1212                    loc: pair.loc(),
1213                },
1214                Rule::string_literal => ValueType::Literal {
1215                    value: Value::String(pair.as_str().to_string()),
1216                    loc: pair.loc(),
1217                },
1218                _ => {
1219                    return Err(ParserError::from(format!(
1220                        "Unexpected rule in BM25Search: {:?}",
1221                        pair.as_rule()
1222                    )));
1223                }
1224            },
1225            None => {
1226                return Err(ParserError::from(format!(
1227                    "Unexpected rule in BM25Search: {:?}",
1228                    pair.as_rule()
1229                )));
1230            }
1231        };
1232        let k = pairs.next().unwrap().as_str().to_string();
1233        Ok(BM25Search {
1234            loc: pair.loc(),
1235            type_arg: Some(vector_type),
1236            data: Some(query),
1237            k: Some(EvaluatesToNumber {
1238                loc: pair.loc(),
1239                value: EvaluatesToNumberType::U32(k.parse::<u32>().unwrap()),
1240            }),
1241        })
1242    }
1243
1244    fn parse_for_loop(&self, pair: Pair<Rule>) -> Result<ForLoop, ParserError> {
1245        let mut pairs = pair.clone().into_inner();
1246        // parse the arguments
1247        let argument = pairs.next().unwrap().clone().into_inner().next().unwrap();
1248        let argument_loc = argument.loc();
1249        let variable = match argument.as_rule() {
1250            Rule::object_destructuring => {
1251                let fields = argument
1252                    .into_inner()
1253                    .into_iter()
1254                    .map(|p| (p.loc(), p.as_str().to_string()))
1255                    .collect();
1256                ForLoopVars::ObjectDestructuring {
1257                    fields,
1258                    loc: argument_loc,
1259                }
1260            }
1261            Rule::object_access => {
1262                let mut inner = argument.clone().into_inner();
1263                let object_name = inner.next().unwrap().as_str().to_string();
1264                let field_name = inner.next().unwrap().as_str().to_string();
1265                ForLoopVars::ObjectAccess {
1266                    name: object_name,
1267                    field: field_name,
1268                    loc: argument_loc,
1269                }
1270            }
1271            Rule::identifier => ForLoopVars::Identifier {
1272                name: argument.as_str().to_string(),
1273                loc: argument_loc,
1274            },
1275            _ => {
1276                return Err(ParserError::from(format!(
1277                    "Unexpected rule in ForLoop: {:?}",
1278                    argument.as_rule()
1279                )));
1280            }
1281        };
1282
1283        // parse the in
1284        let in_ = pairs.next().unwrap().clone();
1285        let in_variable = match in_.as_rule() {
1286            Rule::identifier => (in_.loc(), in_.as_str().to_string()),
1287            _ => {
1288                return Err(ParserError::from(format!(
1289                    "Unexpected rule in ForLoop: {:?}",
1290                    in_.as_rule()
1291                )));
1292            }
1293        };
1294        // parse the body
1295        let statements = self.parse_query_body(pairs.next().unwrap())?;
1296
1297        Ok(ForLoop {
1298            variable,
1299            in_variable,
1300            statements,
1301            loc: pair.loc(),
1302        })
1303    }
1304
1305    fn parse_batch_add_vector(&self, pair: Pair<Rule>) -> Result<BatchAddVector, ParserError> {
1306        let mut vector_type = None;
1307        let mut vec_identifier = None;
1308        let mut fields = None;
1309
1310        for p in pair.clone().into_inner() {
1311            match p.as_rule() {
1312                Rule::identifier_upper => {
1313                    vector_type = Some(p.as_str().to_string());
1314                }
1315                Rule::identifier => {
1316                    vec_identifier = Some(p.as_str().to_string());
1317                }
1318                Rule::create_field => {
1319                    fields = Some(self.parse_property_assignments(p)?);
1320                }
1321                _ => {
1322                    return Err(ParserError::from(format!(
1323                        "Unexpected rule in AddV: {:?} => {:?}",
1324                        p.as_rule(),
1325                        p,
1326                    )));
1327                }
1328            }
1329        }
1330
1331        Ok(BatchAddVector {
1332            vector_type,
1333            vec_identifier,
1334            fields,
1335            loc: pair.loc(),
1336        })
1337    }
1338
1339    fn parse_add_vector(&self, pair: Pair<Rule>) -> Result<AddVector, ParserError> {
1340        let mut vector_type = None;
1341        let mut data = None;
1342        let mut fields = None;
1343
1344        for p in pair.clone().into_inner() {
1345            match p.as_rule() {
1346                Rule::identifier_upper => {
1347                    vector_type = Some(p.as_str().to_string());
1348                }
1349                Rule::vector_data => match p.clone().into_inner().next() {
1350                    Some(vector_data) => match vector_data.as_rule() {
1351                        Rule::identifier => {
1352                            data = Some(VectorData::Identifier(p.as_str().to_string()));
1353                        }
1354                        Rule::vec_literal => {
1355                            data = Some(VectorData::Vector(self.parse_vec_literal(p)?));
1356                        }
1357                        Rule::embed_method => {
1358                            data = Some(VectorData::Embed(Embed {
1359                                loc: vector_data.loc(),
1360                                value: match vector_data.clone().into_inner().next() {
1361                                    Some(inner) => match inner.as_rule() {
1362                                        Rule::identifier => EvaluatesToString::Identifier(
1363                                            inner.as_str().to_string(),
1364                                        ),
1365                                        Rule::string_literal => EvaluatesToString::StringLiteral(
1366                                            inner.as_str().to_string(),
1367                                        ),
1368                                        _ => {
1369                                            return Err(ParserError::from(format!(
1370                                                "Unexpected rule in AddV: {:?} => {:?}",
1371                                                inner.as_rule(),
1372                                                inner,
1373                                            )));
1374                                        }
1375                                    },
1376                                    None => {
1377                                        return Err(ParserError::from(format!(
1378                                            "Unexpected rule in AddV: {:?} => {:?}",
1379                                            p.as_rule(),
1380                                            p,
1381                                        )));
1382                                    }
1383                                },
1384                            }));
1385                        }
1386                        _ => {
1387                            return Err(ParserError::from(format!(
1388                                "Unexpected rule in AddV: {:?} => {:?}",
1389                                vector_data.as_rule(),
1390                                vector_data,
1391                            )));
1392                        }
1393                    },
1394                    None => {
1395                        return Err(ParserError::from(format!(
1396                            "Unexpected rule in AddV: {:?} => {:?}",
1397                            p.as_rule(),
1398                            p,
1399                        )));
1400                    }
1401                },
1402                Rule::create_field => {
1403                    fields = Some(self.parse_property_assignments(p)?);
1404                }
1405                _ => {
1406                    return Err(ParserError::from(format!(
1407                        "Unexpected rule in AddV: {:?} => {:?}",
1408                        p.as_rule(),
1409                        p,
1410                    )));
1411                }
1412            }
1413        }
1414
1415        Ok(AddVector {
1416            vector_type,
1417            data,
1418            fields,
1419            loc: pair.loc(),
1420        })
1421    }
1422
1423    fn parse_search_vector(&self, pair: Pair<Rule>) -> Result<SearchVector, ParserError> {
1424        let mut vector_type = None;
1425        let mut data = None;
1426        let mut k = None;
1427        let mut pre_filter = None;
1428        for p in pair.clone().into_inner() {
1429            match p.as_rule() {
1430                Rule::identifier_upper => {
1431                    vector_type = Some(p.as_str().to_string());
1432                }
1433                Rule::vector_data => match p.clone().into_inner().next() {
1434                    Some(vector_data) => match vector_data.as_rule() {
1435                        Rule::identifier => {
1436                            data = Some(VectorData::Identifier(p.as_str().to_string()));
1437                        }
1438                        Rule::vec_literal => {
1439                            data = Some(VectorData::Vector(self.parse_vec_literal(p)?));
1440                        }
1441                        Rule::embed_method => {
1442                            data = Some(VectorData::Embed(Embed {
1443                                loc: vector_data.loc(),
1444                                value: match vector_data.clone().into_inner().next() {
1445                                    Some(inner) => match inner.as_rule() {
1446                                        Rule::identifier => EvaluatesToString::Identifier(
1447                                            inner.as_str().to_string(),
1448                                        ),
1449                                        Rule::string_literal => EvaluatesToString::StringLiteral(
1450                                            inner.as_str().to_string(),
1451                                        ),
1452                                        _ => {
1453                                            return Err(ParserError::from(format!(
1454                                                "Unexpected rule in SearchV: {:?} => {:?}",
1455                                                inner.as_rule(),
1456                                                inner,
1457                                            )));
1458                                        }
1459                                    },
1460                                    None => {
1461                                        return Err(ParserError::from(format!(
1462                                            "Unexpected rule in SearchV: {:?} => {:?}",
1463                                            p.as_rule(),
1464                                            p,
1465                                        )));
1466                                    }
1467                                },
1468                            }));
1469                        }
1470                        _ => {
1471                            return Err(ParserError::from(format!(
1472                                "Unexpected rule in SearchV: {:?} => {:?}",
1473                                vector_data.as_rule(),
1474                                vector_data,
1475                            )));
1476                        }
1477                    },
1478                    None => {
1479                        return Err(ParserError::from(format!(
1480                            "Unexpected rule in SearchV: {:?} => {:?}",
1481                            p.as_rule(),
1482                            p,
1483                        )));
1484                    }
1485                },
1486                Rule::integer => {
1487                    k = Some(EvaluatesToNumber {
1488                        loc: p.loc(),
1489                        value: EvaluatesToNumberType::I32(
1490                            p.as_str()
1491                                .to_string()
1492                                .parse::<i32>()
1493                                .map_err(|_| ParserError::from("Invalid integer value"))?,
1494                        ),
1495                    });
1496                }
1497                Rule::identifier => {
1498                    k = Some(EvaluatesToNumber {
1499                        loc: p.loc(),
1500                        value: EvaluatesToNumberType::Identifier(p.as_str().to_string()),
1501                    });
1502                }
1503                Rule::pre_filter => {
1504                    pre_filter = Some(Box::new(self.parse_expression(p)?));
1505                }
1506                _ => {
1507                    return Err(ParserError::from(format!(
1508                        "Unexpected rule in SearchV: {:?} => {:?}",
1509                        p.as_rule(),
1510                        p,
1511                    )));
1512                }
1513            }
1514        }
1515
1516        Ok(SearchVector {
1517            loc: pair.loc(),
1518            vector_type,
1519            data,
1520            k,
1521            pre_filter,
1522        })
1523    }
1524
1525    fn parse_vec_literal(&self, pair: Pair<Rule>) -> Result<Vec<f64>, ParserError> {
1526        let pairs = pair.into_inner();
1527        let mut vec = Vec::new();
1528        for p in pairs {
1529            vec.push(
1530                p.as_str()
1531                    .parse::<f64>()
1532                    .map_err(|_| ParserError::from("Invalid float value"))?,
1533            );
1534        }
1535        Ok(vec)
1536    }
1537
1538    fn parse_add_node(&self, pair: Pair<Rule>) -> Result<AddNode, ParserError> {
1539        let mut node_type = None;
1540        let mut fields = None;
1541
1542        for p in pair.clone().into_inner() {
1543            match p.as_rule() {
1544                Rule::identifier_upper => {
1545                    node_type = Some(p.as_str().to_string());
1546                }
1547                Rule::create_field => {
1548                    fields = Some(self.parse_property_assignments(p)?);
1549                }
1550                _ => {
1551                    return Err(ParserError::from(format!(
1552                        "Unexpected rule in AddV: {:?} => {:?}",
1553                        p.as_rule(),
1554                        p,
1555                    )));
1556                }
1557            }
1558        }
1559
1560        Ok(AddNode {
1561            node_type,
1562            fields,
1563            loc: pair.loc(),
1564        })
1565    }
1566
1567    fn parse_property_assignments(
1568        &self,
1569        pair: Pair<Rule>,
1570    ) -> Result<HashMap<String, ValueType>, ParserError> {
1571        pair.into_inner()
1572            .map(|p| {
1573                let mut pairs = p.into_inner();
1574                let prop_key = pairs
1575                    .next()
1576                    .ok_or_else(|| ParserError::from("Missing property key"))?
1577                    .as_str()
1578                    .to_string();
1579
1580                let prop_val = match pairs.next() {
1581                    Some(p) => {
1582                        let value_pair = p
1583                            .into_inner()
1584                            .next()
1585                            .ok_or_else(|| ParserError::from("Empty property value"))?;
1586
1587                        match value_pair.as_rule() {
1588                            Rule::string_literal => Ok(ValueType::new(
1589                                Value::from(value_pair.as_str().to_string()),
1590                                value_pair.loc(),
1591                            )),
1592                            Rule::integer => value_pair
1593                                .as_str()
1594                                .parse()
1595                                .map(|i| ValueType::new(Value::I32(i), value_pair.loc()))
1596                                .map_err(|_| ParserError::from("Invalid integer value")),
1597                            Rule::float => value_pair
1598                                .as_str()
1599                                .parse()
1600                                .map(|f| ValueType::new(Value::F64(f), value_pair.loc()))
1601                                .map_err(|_| ParserError::from("Invalid float value")),
1602                            Rule::boolean => Ok(ValueType::new(
1603                                Value::Boolean(value_pair.as_str() == "true"),
1604                                value_pair.loc(),
1605                            )),
1606                            Rule::identifier => Ok(ValueType::Identifier {
1607                                value: value_pair.as_str().to_string(),
1608                                loc: value_pair.loc(),
1609                            }),
1610                            _ => Err(ParserError::from("Invalid property value type")),
1611                        }?
1612                    }
1613                    None => ValueType::new(Value::Empty, Loc::empty()),
1614                };
1615
1616                Ok((prop_key, prop_val))
1617            })
1618            .collect()
1619    }
1620
1621    fn parse_add_edge(
1622        &self,
1623        pair: Pair<Rule>,
1624        from_identifier: bool,
1625    ) -> Result<AddEdge, ParserError> {
1626        let mut edge_type = None;
1627        let mut fields = None;
1628        let mut connection = None;
1629
1630        for p in pair.clone().into_inner() {
1631            match p.as_rule() {
1632                Rule::identifier_upper => {
1633                    edge_type = Some(p.as_str().to_string());
1634                }
1635                Rule::create_field => {
1636                    fields = Some(self.parse_property_assignments(p)?);
1637                }
1638                Rule::to_from => {
1639                    connection = Some(self.parse_to_from(p)?);
1640                }
1641                _ => {
1642                    return Err(ParserError::from(format!(
1643                        "Unexpected rule in AddE: {:?}",
1644                        p.as_rule()
1645                    )));
1646                }
1647            }
1648        }
1649        if edge_type.is_none() {
1650            return Err(ParserError::from("Missing edge type"));
1651        }
1652        if connection.is_none() {
1653            return Err(ParserError::from("Missing edge connection"));
1654        }
1655        Ok(AddEdge {
1656            edge_type,
1657            fields,
1658            connection: connection.ok_or_else(|| ParserError::from("Missing edge connection"))?,
1659            from_identifier,
1660            loc: pair.loc(),
1661        })
1662    }
1663
1664    fn parse_id_args(&self, pair: Pair<Rule>) -> Result<Option<IdType>, ParserError> {
1665        let p = pair
1666            .into_inner()
1667            .next()
1668            .ok_or_else(|| ParserError::from("Missing ID"))?;
1669        match p.as_rule() {
1670            Rule::identifier => Ok(Some(IdType::Identifier {
1671                value: p.as_str().to_string(),
1672                loc: p.loc(),
1673            })),
1674            Rule::string_literal | Rule::inner_string => Ok(Some(IdType::Literal {
1675                value: p.as_str().to_string(),
1676                loc: p.loc(),
1677            })),
1678            _ => Err(ParserError::from(format!(
1679                "Unexpected rule in parse_id_args: {:?}",
1680                p.as_rule()
1681            ))),
1682        }
1683    }
1684
1685    fn parse_to_from(&self, pair: Pair<Rule>) -> Result<EdgeConnection, ParserError> {
1686        let pairs = pair.clone().into_inner();
1687        let mut from_id = None;
1688        let mut to_id = None;
1689        // println!("pairs: {:?}", pairs);
1690        for p in pairs {
1691            match p.as_rule() {
1692                Rule::from => {
1693                    from_id = self.parse_id_args(p.into_inner().next().unwrap())?;
1694                }
1695                Rule::to => {
1696                    to_id = self.parse_id_args(p.into_inner().next().unwrap())?;
1697                }
1698                _ => unreachable!(),
1699            }
1700        }
1701        Ok(EdgeConnection {
1702            from_id: from_id,
1703            to_id: to_id,
1704            loc: pair.loc(),
1705        })
1706    }
1707
1708    fn parse_get_statement(&self, pair: Pair<Rule>) -> Result<Assignment, ParserError> {
1709        let mut pairs = pair.clone().into_inner();
1710        let variable = pairs.next().unwrap().as_str().to_string();
1711        let value = self.parse_expression(pairs.next().unwrap())?;
1712
1713        Ok(Assignment {
1714            variable,
1715            value,
1716            loc: pair.loc(),
1717        })
1718    }
1719
1720    fn parse_return_statement(&self, pair: Pair<Rule>) -> Result<Vec<Expression>, ParserError> {
1721        // println!("pair: {:?}", pair.clone().into_inner());
1722        pair.into_inner()
1723            .map(|p| self.parse_expression(p))
1724            .collect()
1725    }
1726
1727    fn parse_expression_vec(&self, pairs: Pairs<Rule>) -> Result<Vec<Expression>, ParserError> {
1728        let mut expressions = Vec::new();
1729        for p in pairs {
1730            match p.as_rule() {
1731                Rule::anonymous_traversal => {
1732                    expressions.push(Expression {
1733                        loc: p.loc(),
1734                        expr: ExpressionType::Traversal(Box::new(self.parse_anon_traversal(p)?)),
1735                    });
1736                }
1737                Rule::traversal => {
1738                    expressions.push(Expression {
1739                        loc: p.loc(),
1740                        expr: ExpressionType::Traversal(Box::new(self.parse_traversal(p)?)),
1741                    });
1742                }
1743                Rule::id_traversal => {
1744                    expressions.push(Expression {
1745                        loc: p.loc(),
1746                        expr: ExpressionType::Traversal(Box::new(self.parse_traversal(p)?)),
1747                    });
1748                }
1749                Rule::evaluates_to_bool => {
1750                    expressions.push(self.parse_boolean_expression(p)?);
1751                }
1752                _ => unreachable!(),
1753            }
1754        }
1755        Ok(expressions)
1756    }
1757
1758    fn parse_boolean_expression(&self, pair: Pair<Rule>) -> Result<Expression, ParserError> {
1759        let expression = pair.into_inner().next().unwrap();
1760        match expression.as_rule() {
1761            Rule::and => Ok(Expression {
1762                loc: expression.loc(),
1763                expr: ExpressionType::And(self.parse_expression_vec(expression.into_inner())?),
1764            }),
1765            Rule::or => Ok(Expression {
1766                loc: expression.loc(),
1767                expr: ExpressionType::Or(self.parse_expression_vec(expression.into_inner())?),
1768            }),
1769            Rule::boolean => Ok(Expression {
1770                loc: expression.loc(),
1771                expr: ExpressionType::BooleanLiteral(expression.as_str() == "true"),
1772            }),
1773            Rule::exists => Ok(Expression {
1774                loc: expression.loc(),
1775                expr: ExpressionType::Exists(Box::new(Expression {
1776                    loc: expression.loc(),
1777                    expr: ExpressionType::Traversal(Box::new(
1778                        self.parse_anon_traversal(expression.into_inner().next().unwrap())?,
1779                    )),
1780                })),
1781            }),
1782
1783            _ => unreachable!(),
1784        }
1785    }
1786
1787    fn parse_expression(&self, p: Pair<Rule>) -> Result<Expression, ParserError> {
1788        let pair = p
1789            .into_inner()
1790            .next()
1791            .ok_or_else(|| ParserError::from("Empty expression"))?;
1792
1793        match pair.as_rule() {
1794            Rule::traversal => Ok(Expression {
1795                loc: pair.loc(),
1796                expr: ExpressionType::Traversal(Box::new(self.parse_traversal(pair)?)),
1797            }),
1798            Rule::id_traversal => Ok(Expression {
1799                loc: pair.loc(),
1800                expr: ExpressionType::Traversal(Box::new(self.parse_traversal(pair)?)),
1801            }),
1802            Rule::anonymous_traversal => Ok(Expression {
1803                loc: pair.loc(),
1804                expr: ExpressionType::Traversal(Box::new(self.parse_anon_traversal(pair)?)),
1805            }),
1806            Rule::identifier => Ok(Expression {
1807                loc: pair.loc(),
1808                expr: ExpressionType::Identifier(pair.as_str().to_string()),
1809            }),
1810            Rule::string_literal => Ok(Expression {
1811                loc: pair.loc(),
1812                expr: ExpressionType::StringLiteral(self.parse_string_literal(pair)?),
1813            }),
1814            Rule::exists => {
1815                let traversal = pair
1816                    .clone()
1817                    .into_inner()
1818                    .next()
1819                    .ok_or_else(|| ParserError::from("Missing exists traversal"))?;
1820                Ok(Expression {
1821                    loc: pair.loc(),
1822                    expr: ExpressionType::Exists(Box::new(Expression {
1823                        loc: pair.loc(),
1824                        expr: ExpressionType::Traversal(Box::new(match traversal.as_rule() {
1825                            Rule::traversal => self.parse_traversal(traversal)?,
1826                            Rule::id_traversal => self.parse_traversal(traversal)?,
1827                            _ => unreachable!(),
1828                        })),
1829                    })),
1830                })
1831            }
1832            Rule::integer => pair
1833                .as_str()
1834                .parse()
1835                .map(|i| Expression {
1836                    loc: pair.loc(),
1837                    expr: ExpressionType::IntegerLiteral(i),
1838                })
1839                .map_err(|_| ParserError::from("Invalid integer literal")),
1840            Rule::float => pair
1841                .as_str()
1842                .parse()
1843                .map(|f| Expression {
1844                    loc: pair.loc(),
1845                    expr: ExpressionType::FloatLiteral(f),
1846                })
1847                .map_err(|_| ParserError::from("Invalid float literal")),
1848            Rule::boolean => Ok(Expression {
1849                loc: pair.loc(),
1850                expr: ExpressionType::BooleanLiteral(pair.as_str() == "true"),
1851            }),
1852            Rule::evaluates_to_bool => Ok(self.parse_boolean_expression(pair)?),
1853            Rule::AddN => Ok(Expression {
1854                loc: pair.loc(),
1855                expr: ExpressionType::AddNode(self.parse_add_node(pair)?),
1856            }),
1857            Rule::AddV => Ok(Expression {
1858                loc: pair.loc(),
1859                expr: ExpressionType::AddVector(self.parse_add_vector(pair)?),
1860            }),
1861            Rule::BatchAddV => Ok(Expression {
1862                loc: pair.loc(),
1863                expr: ExpressionType::BatchAddVector(self.parse_batch_add_vector(pair)?),
1864            }),
1865            Rule::AddE => Ok(Expression {
1866                loc: pair.loc(),
1867                expr: ExpressionType::AddEdge(self.parse_add_edge(pair, false)?),
1868            }),
1869            Rule::search_vector => Ok(Expression {
1870                loc: pair.loc(),
1871                expr: ExpressionType::SearchVector(self.parse_search_vector(pair)?),
1872            }),
1873            Rule::none => Ok(Expression {
1874                loc: pair.loc(),
1875                expr: ExpressionType::Empty,
1876            }),
1877            Rule::bm25_search => Ok(Expression {
1878                loc: pair.loc(),
1879                expr: ExpressionType::BM25Search(self.parse_bm25_search(pair)?),
1880            }),
1881            _ => Err(ParserError::from(format!(
1882                "Unexpected expression type: {:?}",
1883                pair.as_rule()
1884            ))),
1885        }
1886    }
1887
1888    fn parse_string_literal(&self, pair: Pair<Rule>) -> Result<String, ParserError> {
1889        let inner = pair
1890            .into_inner()
1891            .next()
1892            .ok_or_else(|| ParserError::from("Empty string literal"))?;
1893
1894        let mut literal = inner.as_str().to_string();
1895        literal.retain(|c| c != '"');
1896        Ok(literal)
1897    }
1898
1899    fn parse_traversal(&self, pair: Pair<Rule>) -> Result<Traversal, ParserError> {
1900        let mut pairs = pair.clone().into_inner();
1901        let start = self.parse_start_node(pairs.next().unwrap())?;
1902        let steps = pairs
1903            .map(|p| self.parse_step(p))
1904            .collect::<Result<Vec<_>, _>>()?;
1905
1906        Ok(Traversal {
1907            start,
1908            steps,
1909            loc: pair.loc(),
1910        })
1911    }
1912
1913    fn parse_anon_traversal(&self, pair: Pair<Rule>) -> Result<Traversal, ParserError> {
1914        let pairs = pair.clone().into_inner();
1915        let start = StartNode::Anonymous;
1916        let steps = pairs
1917            .map(|p| self.parse_step(p))
1918            .collect::<Result<Vec<_>, _>>()?;
1919
1920        Ok(Traversal {
1921            start,
1922            steps,
1923            loc: pair.loc(),
1924        })
1925    }
1926
1927    fn parse_start_node(&self, pair: Pair<Rule>) -> Result<StartNode, ParserError> {
1928        match pair.as_rule() {
1929            Rule::start_node => {
1930                let pairs = pair.into_inner();
1931                let mut node_type = String::new();
1932                let mut ids = None;
1933                for p in pairs {
1934                    match p.as_rule() {
1935                        Rule::type_args => {
1936                            node_type = p.into_inner().next().unwrap().as_str().to_string();
1937                            // WATCH
1938                        }
1939                        Rule::id_args => {
1940                            ids = Some(
1941                                p.into_inner()
1942                                    .map(|id| {
1943                                        let id = id.into_inner().next().unwrap();
1944                                        match id.as_rule() {
1945                                            Rule::identifier => IdType::Identifier {
1946                                                value: id.as_str().to_string(),
1947                                                loc: id.loc(),
1948                                            },
1949                                            Rule::string_literal => IdType::Literal {
1950                                                value: id.as_str().to_string(),
1951                                                loc: id.loc(),
1952                                            },
1953                                            _ => {
1954                                                panic!("Should be identifier or string literal")
1955                                            }
1956                                        }
1957                                    })
1958                                    .collect::<Vec<_>>(),
1959                            );
1960                        }
1961                        Rule::by_index => {
1962                            ids = Some({
1963                                let mut pairs: Pairs<'_, Rule> = p.clone().into_inner();
1964                                let index = match pairs.next().unwrap().clone().into_inner().next()
1965                                {
1966                                    Some(id) => match id.as_rule() {
1967                                        Rule::identifier => IdType::Identifier {
1968                                            value: id.as_str().to_string(),
1969                                            loc: id.loc(),
1970                                        },
1971                                        Rule::string_literal => IdType::Literal {
1972                                            value: id.as_str().to_string(),
1973                                            loc: id.loc(),
1974                                        },
1975                                        other => {
1976                                            panic!(
1977                                                "Should be identifier or string literal: {:?}",
1978                                                other
1979                                            )
1980                                        }
1981                                    },
1982                                    None => return Err(ParserError::from("Missing index")),
1983                                };
1984                                let value = match pairs.next().unwrap().into_inner().next() {
1985                                    Some(val) => match val.as_rule() {
1986                                        Rule::identifier => ValueType::Identifier {
1987                                            value: val.as_str().to_string(),
1988                                            loc: val.loc(),
1989                                        },
1990                                        Rule::string_literal => ValueType::Literal {
1991                                            value: Value::from(val.as_str()),
1992                                            loc: val.loc(),
1993                                        },
1994                                        Rule::integer => ValueType::Literal {
1995                                            value: Value::from(
1996                                                val.as_str().parse::<i64>().unwrap(),
1997                                            ),
1998                                            loc: val.loc(),
1999                                        },
2000                                        Rule::float => ValueType::Literal {
2001                                            value: Value::from(
2002                                                val.as_str().parse::<f64>().unwrap(),
2003                                            ),
2004                                            loc: val.loc(),
2005                                        },
2006                                        Rule::boolean => ValueType::Literal {
2007                                            value: Value::from(
2008                                                val.as_str().parse::<bool>().unwrap(),
2009                                            ),
2010                                            loc: val.loc(),
2011                                        },
2012                                        _ => {
2013                                            panic!("Should be identifier or string literal")
2014                                        }
2015                                    },
2016                                    _ => unreachable!(),
2017                                };
2018                                vec![IdType::ByIndex {
2019                                    index: Box::new(index),
2020                                    value: Box::new(value),
2021                                    loc: p.loc(),
2022                                }]
2023                            })
2024                        }
2025                        _ => unreachable!(),
2026                    }
2027                }
2028                Ok(StartNode::Node { node_type, ids })
2029            }
2030            Rule::start_edge => {
2031                let pairs = pair.into_inner();
2032                let mut edge_type = String::new();
2033                let mut ids = None;
2034                for p in pairs {
2035                    match p.as_rule() {
2036                        Rule::type_args => {
2037                            edge_type = p.into_inner().next().unwrap().as_str().to_string();
2038                        }
2039                        Rule::id_args => {
2040                            ids = Some(
2041                                p.into_inner()
2042                                    .map(|id| {
2043                                        let id = id.into_inner().next().unwrap();
2044                                        match id.as_rule() {
2045                                            Rule::identifier => IdType::Identifier {
2046                                                value: id.as_str().to_string(),
2047                                                loc: id.loc(),
2048                                            },
2049                                            Rule::string_literal => IdType::Literal {
2050                                                value: id.as_str().to_string(),
2051                                                loc: id.loc(),
2052                                            },
2053                                            other => {
2054                                                println!("{:?}", other);
2055                                                panic!("Should be identifier or string literal")
2056                                            }
2057                                        }
2058                                    })
2059                                    .collect::<Vec<_>>(),
2060                            );
2061                        }
2062                        _ => unreachable!(),
2063                    }
2064                }
2065                Ok(StartNode::Edge { edge_type, ids })
2066            }
2067            Rule::identifier => Ok(StartNode::Identifier(pair.as_str().to_string())),
2068            _ => Ok(StartNode::Anonymous),
2069        }
2070    }
2071
2072    fn parse_step(&self, pair: Pair<Rule>) -> Result<Step, ParserError> {
2073        let inner = pair.clone().into_inner().next().unwrap();
2074        match inner.as_rule() {
2075            Rule::graph_step => Ok(Step {
2076                loc: inner.loc(),
2077                step: StepType::Node(self.parse_graph_step(inner)),
2078            }),
2079            Rule::object_step => Ok(Step {
2080                loc: inner.loc(),
2081                step: StepType::Object(self.parse_object_step(inner)?),
2082            }),
2083            Rule::closure_step => Ok(Step {
2084                loc: inner.loc(),
2085                step: StepType::Closure(self.parse_closure(inner)?),
2086            }),
2087            Rule::where_step => Ok(Step {
2088                loc: inner.loc(),
2089                step: StepType::Where(Box::new(self.parse_expression(inner)?)),
2090            }),
2091            Rule::range_step => Ok(Step {
2092                loc: inner.loc(),
2093                step: StepType::Range(self.parse_range(pair)?),
2094            }),
2095
2096            Rule::bool_operations => Ok(Step {
2097                loc: inner.loc(),
2098                step: StepType::BooleanOperation(self.parse_bool_operation(inner)?),
2099            }),
2100            Rule::count => Ok(Step {
2101                loc: inner.loc(),
2102                step: StepType::Count,
2103            }),
2104            Rule::ID => Ok(Step {
2105                loc: inner.loc(),
2106                step: StepType::Object(Object {
2107                    fields: vec![FieldAddition {
2108                        key: "id".to_string(),
2109                        value: FieldValue {
2110                            loc: pair.loc(),
2111                            value: FieldValueType::Identifier("id".to_string()),
2112                        },
2113                        loc: pair.loc(),
2114                    }],
2115                    should_spread: false,
2116                    loc: pair.loc(),
2117                }),
2118            }),
2119            Rule::update => Ok(Step {
2120                loc: inner.loc(),
2121                step: StepType::Update(self.parse_update(inner)?),
2122            }),
2123            Rule::exclude_field => Ok(Step {
2124                loc: inner.loc(),
2125                step: StepType::Exclude(self.parse_exclude(inner)?),
2126            }),
2127            Rule::AddE => Ok(Step {
2128                loc: inner.loc(),
2129                step: StepType::AddEdge(self.parse_add_edge(inner, true)?),
2130            }),
2131            Rule::order_by_asc => Ok(Step {
2132                loc: inner.loc(),
2133                step: StepType::OrderByAsc(Box::new(self.parse_expression(inner)?)),
2134            }),
2135            Rule::order_by_desc => Ok(Step {
2136                loc: inner.loc(),
2137                step: StepType::OrderByDesc(Box::new(self.parse_expression(inner)?)),
2138            }),
2139            _ => Err(ParserError::from(format!(
2140                "Unexpected step type: {:?}",
2141                inner.as_rule()
2142            ))),
2143        }
2144    }
2145
2146    fn parse_range(&self, pair: Pair<Rule>) -> Result<(Expression, Expression), ParserError> {
2147        let mut inner = pair.into_inner().next().unwrap().into_inner();
2148        // println!("inner: {:?}", inner);
2149        let start = match self.parse_expression(inner.next().unwrap()) {
2150            Ok(val) => val,
2151            Err(e) => return Err(e),
2152        };
2153        let end = match self.parse_expression(inner.next().unwrap()) {
2154            Ok(val) => val,
2155            Err(e) => return Err(e),
2156        };
2157
2158        Ok((start, end))
2159    }
2160
2161    fn parse_graph_step(&self, pair: Pair<Rule>) -> GraphStep {
2162        let types = |pair: &Pair<Rule>| {
2163            pair.clone()
2164                .into_inner()
2165                .next()
2166                .map(|p| p.as_str().to_string())
2167                .ok_or_else(|| ParserError::from("Expected type".to_string()))
2168                .unwrap()
2169        }; // TODO: change to error
2170        let pair = pair.into_inner().next().unwrap(); // TODO: change to error
2171        match pair.as_rule() {
2172            // s if s.starts_with("OutE") => GraphStep {
2173            //     loc: pair.loc(),
2174            //     step: GraphStepType::OutE(types),
2175            // },
2176            // s if s.starts_with("InE") => GraphStep {
2177            //     loc: pair.loc(),
2178            //     step: GraphStepType::InE(types),
2179            // },
2180            // s if s.starts_with("FromN") => GraphStep {
2181            //     loc: pair.loc(),
2182            //     step: GraphStepType::FromN,
2183            // },
2184            // s if s.starts_with("ToN") => GraphStep {
2185            //     loc: pair.loc(),
2186            //     step: GraphStepType::ToN,
2187            // },
2188            // s if s.starts_with("Out") => GraphStep {
2189            //     loc: pair.loc(),
2190            //     step: GraphStepType::Out(types),
2191            // },
2192            // s if s.starts_with("In") => GraphStep {
2193            //     loc: pair.loc(),
2194            //     step: GraphStepType::In(types),
2195            // },
2196            // _ => {
2197            //     println!("rule_str: {:?}", rule_str);
2198            //     unreachable!()
2199            // }
2200            Rule::out_e => {
2201                let types = types(&pair);
2202                GraphStep {
2203                    loc: pair.loc(),
2204                    step: GraphStepType::OutE(types),
2205                }
2206            }
2207            Rule::in_e => {
2208                let types = types(&pair);
2209                GraphStep {
2210                    loc: pair.loc(),
2211                    step: GraphStepType::InE(types),
2212                }
2213            }
2214            Rule::from_n => GraphStep {
2215                loc: pair.loc(),
2216                step: GraphStepType::FromN,
2217            },
2218            Rule::to_n => GraphStep {
2219                loc: pair.loc(),
2220                step: GraphStepType::ToN,
2221            },
2222            Rule::from_v => GraphStep {
2223                loc: pair.loc(),
2224                step: GraphStepType::FromV,
2225            },
2226            Rule::to_v => GraphStep {
2227                loc: pair.loc(),
2228                step: GraphStepType::ToV,
2229            },
2230            Rule::out => {
2231                let types = types(&pair);
2232                GraphStep {
2233                    loc: pair.loc(),
2234                    step: GraphStepType::Out(types),
2235                }
2236            }
2237            Rule::in_nodes => {
2238                let types = types(&pair);
2239                GraphStep {
2240                    loc: pair.loc(),
2241                    step: GraphStepType::In(types),
2242                }
2243            }
2244            Rule::shortest_path => {
2245                let (type_arg, from, to) = pair.clone().into_inner().fold(
2246                    (None, None, None),
2247                    |(type_arg, from, to), p| match p.as_rule() {
2248                        Rule::type_args => (
2249                            Some(p.into_inner().next().unwrap().as_str().to_string()),
2250                            from,
2251                            to,
2252                        ),
2253                        Rule::to_from => match p.into_inner().next() {
2254                            Some(p) => match p.as_rule() {
2255                                Rule::to => (
2256                                    type_arg,
2257                                    from,
2258                                    Some(p.into_inner().next().unwrap().as_str().to_string()),
2259                                ),
2260                                Rule::from => (
2261                                    type_arg,
2262                                    Some(p.into_inner().next().unwrap().as_str().to_string()),
2263                                    to,
2264                                ),
2265                                _ => unreachable!(),
2266                            },
2267                            None => (type_arg, from, to),
2268                        },
2269                        _ => (type_arg, from, to),
2270                    },
2271                );
2272
2273                // TODO: add error handling and check about IdType as might not always be data.
2274                // possibly use stack to keep track of variables and use them via precedence and then check on type
2275                // e.g. if valid variable and is param then use data. otherwise use plain identifier
2276                GraphStep {
2277                    loc: pair.loc(),
2278                    step: GraphStepType::ShortestPath(ShortestPath {
2279                        loc: pair.loc(),
2280                        from: from.map(|id| IdType::Identifier {
2281                            value: id,
2282                            loc: pair.loc(),
2283                        }),
2284                        to: to.map(|id| IdType::Identifier {
2285                            value: id,
2286                            loc: pair.loc(),
2287                        }),
2288                        type_arg,
2289                    }),
2290                }
2291            }
2292            Rule::search_vector => GraphStep {
2293                loc: pair.loc(),
2294                step: GraphStepType::SearchVector(self.parse_search_vector(pair).unwrap()),
2295            },
2296            _ => {
2297                println!("rule_str: {:?}", pair.as_str());
2298                unreachable!()
2299            }
2300        }
2301    }
2302
2303    fn parse_bool_operation(&self, pair: Pair<Rule>) -> Result<BooleanOp, ParserError> {
2304        let inner = pair.clone().into_inner().next().unwrap();
2305        let expr = match inner.as_rule() {
2306            Rule::GT => BooleanOp {
2307                loc: pair.loc(),
2308                op: BooleanOpType::GreaterThan(Box::new(
2309                    self.parse_expression(inner.into_inner().next().unwrap())?,
2310                )),
2311            },
2312            Rule::GTE => BooleanOp {
2313                loc: pair.loc(),
2314                op: BooleanOpType::GreaterThanOrEqual(Box::new(
2315                    self.parse_expression(inner.into_inner().next().unwrap())?,
2316                )),
2317            },
2318            Rule::LT => BooleanOp {
2319                loc: pair.loc(),
2320                op: BooleanOpType::LessThan(Box::new(
2321                    self.parse_expression(inner.into_inner().next().unwrap())?,
2322                )),
2323            },
2324            Rule::LTE => BooleanOp {
2325                loc: pair.loc(),
2326                op: BooleanOpType::LessThanOrEqual(Box::new(
2327                    self.parse_expression(inner.into_inner().next().unwrap())?,
2328                )),
2329            },
2330            Rule::EQ => BooleanOp {
2331                loc: pair.loc(),
2332                op: BooleanOpType::Equal(Box::new(
2333                    self.parse_expression(inner.into_inner().next().unwrap())?,
2334                )),
2335            },
2336            Rule::NEQ => BooleanOp {
2337                loc: pair.loc(),
2338                op: BooleanOpType::NotEqual(Box::new(
2339                    self.parse_expression(inner.into_inner().next().unwrap())?,
2340                )),
2341            },
2342            _ => return Err(ParserError::from("Invalid boolean operation")),
2343        };
2344        Ok(expr)
2345    }
2346
2347    fn parse_field_additions(&self, pair: Pair<Rule>) -> Result<Vec<FieldAddition>, ParserError> {
2348        pair.into_inner()
2349            .map(|p| self.parse_new_field_pair(p))
2350            .collect()
2351    }
2352
2353    fn parse_new_field_pair(&self, pair: Pair<Rule>) -> Result<FieldAddition, ParserError> {
2354        let mut pairs = pair.clone().into_inner();
2355        let key = pairs.next().unwrap().as_str().to_string();
2356        let value_pair = pairs.next().unwrap();
2357
2358        let value: FieldValue = match value_pair.as_rule() {
2359            Rule::evaluates_to_anything => FieldValue {
2360                loc: value_pair.loc(),
2361                value: FieldValueType::Expression(self.parse_expression(value_pair)?),
2362            },
2363            Rule::anonymous_traversal => FieldValue {
2364                loc: value_pair.loc(),
2365                value: FieldValueType::Traversal(Box::new(self.parse_traversal(value_pair)?)),
2366            },
2367            Rule::object_step => FieldValue {
2368                loc: value_pair.loc(),
2369                value: FieldValueType::Fields(self.parse_field_additions(value_pair)?),
2370            },
2371            Rule::string_literal => {
2372                println!("string_literal: {:?}", value_pair);
2373                FieldValue {
2374                    loc: value_pair.loc(),
2375                    value: FieldValueType::Literal(Value::String(
2376                        self.parse_string_literal(value_pair)?,
2377                    )),
2378                }
2379            }
2380            Rule::integer => FieldValue {
2381                loc: value_pair.loc(),
2382                value: FieldValueType::Literal(Value::I32(
2383                    value_pair
2384                        .as_str()
2385                        .parse()
2386                        .map_err(|_| ParserError::from("Invalid integer literal"))?,
2387                )),
2388            },
2389            Rule::float => FieldValue {
2390                loc: value_pair.loc(),
2391                value: FieldValueType::Literal(Value::F64(
2392                    value_pair
2393                        .as_str()
2394                        .parse()
2395                        .map_err(|_| ParserError::from("Invalid float literal"))?,
2396                )),
2397            },
2398            Rule::boolean => FieldValue {
2399                loc: value_pair.loc(),
2400                value: FieldValueType::Literal(Value::Boolean(value_pair.as_str() == "true")),
2401            },
2402            Rule::none => FieldValue {
2403                loc: value_pair.loc(),
2404                value: FieldValueType::Empty,
2405            },
2406            Rule::mapping_field => FieldValue {
2407                loc: value_pair.loc(),
2408                value: FieldValueType::Fields(self.parse_field_additions(value_pair)?),
2409            },
2410            _ => {
2411                return Err(ParserError::from(format!(
2412                    "Unexpected field pair type: {:?} \n {:?} \n\n {:?}",
2413                    value_pair.as_rule(),
2414                    value_pair,
2415                    pair
2416                )));
2417            }
2418        };
2419
2420        Ok(FieldAddition {
2421            loc: pair.loc(),
2422            key,
2423            value,
2424        })
2425    }
2426
2427    fn parse_new_field_value(&self, pair: Pair<Rule>) -> Result<FieldValue, ParserError> {
2428        let value_pair = pair.into_inner().next().unwrap();
2429        let value: FieldValue = match value_pair.as_rule() {
2430            Rule::evaluates_to_anything => FieldValue {
2431                loc: value_pair.loc(),
2432                value: FieldValueType::Expression(self.parse_expression(value_pair)?),
2433            },
2434            Rule::anonymous_traversal => FieldValue {
2435                loc: value_pair.loc(),
2436                value: FieldValueType::Traversal(Box::new(self.parse_traversal(value_pair)?)),
2437            },
2438            Rule::object_step => FieldValue {
2439                loc: value_pair.loc(),
2440                value: FieldValueType::Fields(self.parse_field_additions(value_pair)?),
2441            },
2442            Rule::string_literal => FieldValue {
2443                loc: value_pair.loc(),
2444                value: FieldValueType::Literal(Value::String(
2445                    self.parse_string_literal(value_pair)?,
2446                )),
2447            },
2448            Rule::integer => FieldValue {
2449                loc: value_pair.loc(),
2450                value: FieldValueType::Literal(Value::I32(
2451                    value_pair
2452                        .as_str()
2453                        .parse()
2454                        .map_err(|_| ParserError::from("Invalid integer literal"))?,
2455                )),
2456            },
2457            Rule::float => FieldValue {
2458                loc: value_pair.loc(),
2459                value: FieldValueType::Literal(Value::F64(
2460                    value_pair
2461                        .as_str()
2462                        .parse()
2463                        .map_err(|_| ParserError::from("Invalid float literal"))?,
2464                )),
2465            },
2466            Rule::boolean => FieldValue {
2467                loc: value_pair.loc(),
2468                value: FieldValueType::Literal(Value::Boolean(value_pair.as_str() == "true")),
2469            },
2470            Rule::none => FieldValue {
2471                loc: value_pair.loc(),
2472                value: FieldValueType::Empty,
2473            },
2474            Rule::mapping_field => FieldValue {
2475                loc: value_pair.loc(),
2476                value: FieldValueType::Fields(self.parse_field_additions(value_pair)?),
2477            },
2478            _ => {
2479                return Err(ParserError::from(format!(
2480                    "Unexpected field value type: {:?} \n {:?}",
2481                    value_pair.as_rule(),
2482                    value_pair,
2483                )));
2484            }
2485        };
2486
2487        Ok(value)
2488    }
2489
2490    fn parse_update(&self, pair: Pair<Rule>) -> Result<Update, ParserError> {
2491        let fields = self.parse_field_additions(pair.clone())?;
2492        Ok(Update {
2493            fields,
2494            loc: pair.loc(),
2495        })
2496    }
2497
2498    fn parse_object_step(&self, pair: Pair<Rule>) -> Result<Object, ParserError> {
2499        let mut fields = Vec::new();
2500        let mut should_spread = false;
2501        for p in pair.clone().into_inner() {
2502            if p.as_rule() == Rule::spread_object {
2503                should_spread = true;
2504                continue;
2505            }
2506            let mut pairs = p.clone().into_inner();
2507            let prop_key = pairs.next().unwrap().as_str().to_string();
2508            let field_addition = match pairs.next() {
2509                Some(p) => match p.as_rule() {
2510                    Rule::evaluates_to_anything => FieldValue {
2511                        loc: p.loc(),
2512                        value: FieldValueType::Expression(self.parse_expression(p)?),
2513                    },
2514                    Rule::anonymous_traversal => FieldValue {
2515                        loc: p.loc(),
2516                        value: FieldValueType::Traversal(Box::new(self.parse_anon_traversal(p)?)),
2517                    },
2518                    Rule::mapping_field => FieldValue {
2519                        loc: p.loc(),
2520                        value: FieldValueType::Fields(self.parse_field_additions(p)?),
2521                    },
2522                    Rule::object_step => FieldValue {
2523                        loc: p.clone().loc(),
2524                        value: FieldValueType::Fields(self.parse_object_step(p.clone())?.fields),
2525                    },
2526                    _ => self.parse_new_field_value(p)?,
2527                },
2528                None if prop_key.len() > 0 => FieldValue {
2529                    loc: p.loc(),
2530                    value: FieldValueType::Identifier(prop_key.clone()),
2531                },
2532                None => FieldValue {
2533                    loc: p.loc(),
2534                    value: FieldValueType::Empty,
2535                },
2536            };
2537            fields.push(FieldAddition {
2538                loc: p.loc(),
2539                key: prop_key,
2540                value: field_addition,
2541            });
2542        }
2543        Ok(Object {
2544            loc: pair.loc(),
2545            fields,
2546            should_spread,
2547        })
2548    }
2549
2550    fn parse_closure(&self, pair: Pair<Rule>) -> Result<Closure, ParserError> {
2551        let mut pairs = pair.clone().into_inner();
2552        let identifier = pairs.next().unwrap().as_str().to_string();
2553        let object = self.parse_object_step(pairs.next().unwrap())?;
2554        Ok(Closure {
2555            loc: pair.loc(),
2556            identifier,
2557            object,
2558        })
2559    }
2560
2561    fn parse_exclude(&self, pair: Pair<Rule>) -> Result<Exclude, ParserError> {
2562        let mut fields = Vec::new();
2563        for p in pair.clone().into_inner() {
2564            fields.push((p.loc(), p.as_str().to_string()));
2565        }
2566        Ok(Exclude {
2567            loc: pair.loc(),
2568            fields,
2569        })
2570    }
2571}
2572
2573pub fn write_to_temp_file(content: Vec<&str>) -> Content {
2574    let mut files = Vec::new();
2575    for c in content {
2576        let mut file = tempfile::NamedTempFile::new().unwrap();
2577        file.write_all(c.as_bytes()).unwrap();
2578        let path = file.path().to_string_lossy().into_owned();
2579        files.push(HxFile {
2580            name: path,
2581            content: c.to_string(),
2582        });
2583    }
2584    Content {
2585        content: String::new(),
2586        files: files,
2587        source: Source::default(),
2588    }
2589}