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#[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 }
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 _ => 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 } }
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 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 remaining.insert(pair);
811 }
812 Rule::EOI => (),
813 _ => return Err(ParserError::from("Unexpected rule encountered")),
814 }
815 }
816
817 for pair in remaining {
818 parser
820 .source
821 .queries
822 .push(parser.parse_query_def(pair, file.name.clone())?);
823 }
824
825 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 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 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 let prefix: FieldPrefix = match pairs.clone().next().unwrap().as_rule() {
948 Rule::index => {
949 pairs.next().unwrap();
950 FieldPrefix::Index
951 }
952 _ => 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!(), }
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!(), }
1013 }
1014 Rule::now => DefaultValue::Now,
1015 Rule::boolean => {
1016 DefaultValue::Boolean(pair.as_str().parse::<bool>().unwrap())
1017 }
1018 _ => unreachable!(), },
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 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 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 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 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 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 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 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 }
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 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 }; let pair = pair.into_inner().next().unwrap(); match pair.as_rule() {
2172 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 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}