1use crate::conversion::{BorrowFromGValue, FromGValue};
2use crate::process::traversal::{Bytecode, Order, Scope, TerminatorToken};
3use crate::structure::traverser::Traverser;
4use crate::structure::{
5 label::LabelType, Cardinality, Edge, GKey, IntermediateRepr, List, Map, Metric, Path, Property,
6 Set, Token, TraversalExplanation, TraversalMetrics, Vertex, VertexProperty,
7};
8use crate::structure::{Pop, Predicate, TextP, T};
9use crate::{GremlinError, GremlinResult};
10use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
11pub type Date = chrono::DateTime<chrono::offset::Utc>;
12use std::convert::TryInto;
13use std::hash::Hash;
14#[allow(clippy::large_enum_variant)]
16#[derive(Debug, PartialEq, Clone)]
17pub enum GValue {
18 Null,
19 Vertex(Vertex),
20 Edge(Edge),
21 Bytes(Vec<u8>),
22 VertexProperty(VertexProperty),
23 Property(Property),
24 Uuid(uuid::Uuid),
25 Int32(i32),
26 Int64(i64),
27 Float(f32),
28 Double(f64),
29 Date(Date),
30 List(List),
31 Set(Set),
32 Map(Map),
33 Token(Token),
34 String(String),
35 Path(Path),
36 TraversalMetrics(TraversalMetrics),
37 Metric(Metric),
38 TraversalExplanation(TraversalExplanation),
39 IntermediateRepr(IntermediateRepr),
40 P(Predicate),
41 T(T),
42 Bytecode(Bytecode),
43 Traverser(Traverser),
44 Scope(Scope),
45 Order(Order),
46 Bool(bool),
47 TextP(TextP),
48 Pop(Pop),
49 Terminator(TerminatorToken),
50 Cardinality(Cardinality),
51}
52
53impl PartialOrd for GValue {
54 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
55 match self {
56 GValue::Int32(v) => v.partial_cmp(other.get::<i32>().unwrap()),
57 GValue::Int64(v) => v.partial_cmp(other.get::<i64>().unwrap()),
58 GValue::Float(v) => v.partial_cmp(other.get::<f32>().unwrap()),
59 GValue::Double(v) => v.partial_cmp(other.get::<f64>().unwrap()),
60 GValue::Date(v) => v.partial_cmp(other.get::<Date>().unwrap()),
61 GValue::String(v) => v.partial_cmp(other.get::<String>().unwrap()),
62 _ => unimplemented!(),
63 }
64 }
65}
66
67impl GValue {
68 pub fn from_bytes(variant: usize, bytes: Vec<u8>) -> GValue {
69 match variant {
70 1 => GValue::String(String::from_utf8(bytes).unwrap()),
71 2 => {
72 let mut slice = [Default::default(); 4];
73 slice.copy_from_slice(&bytes);
74 GValue::Int32(i32::from_be_bytes(slice))
75 }
76 3 => {
77 let mut slice = [Default::default(); 8];
78 slice.copy_from_slice(&bytes);
79 GValue::Int64(i64::from_be_bytes(slice))
80 }
81 4 => GValue::Bool(*bytes.last().unwrap() == 0),
82 5 => {
83 let mut slice = [Default::default(); 4];
84 slice.copy_from_slice(&bytes);
85 GValue::Float(f32::from_be_bytes(slice))
86 }
87 8 => GValue::Bytes(bytes),
88 _ => unimplemented!(),
89 }
90 }
91
92 pub fn to_variant(&self) -> u8 {
93 match self {
94 GValue::String(_) => 1,
95 GValue::Int32(_) => 2,
96 GValue::Int64(_) => 3,
97 GValue::Bool(_) => 4,
98 GValue::Float(_) => 5,
99 GValue::Vertex(_) => 6,
100 GValue::VertexProperty(_) => 7,
101 GValue::Bytes(_) => 8,
102 GValue::Edge(_) => 9,
103 GValue::Double(_) => 10,
104 GValue::Cardinality(_) => 11,
105 GValue::Set(_) => 12,
106 GValue::P(_) => 13,
107 _ => unimplemented!(),
108 }
109 }
110
111 pub fn is_null(&self) -> bool {
112 matches!(self, GValue::Null)
113 }
114
115 pub fn bytes(&self) -> Vec<u8> {
116 match self {
117 GValue::String(v) => v.as_bytes().to_vec(),
118 GValue::Int32(v) => v.to_be_bytes().to_vec(),
119 GValue::Int64(v) => v.to_be_bytes().to_vec(),
120 GValue::Bytes(v) => v.to_vec(),
121 _ => unimplemented!(),
122 }
123 }
124
125 pub fn take<T>(self) -> GremlinResult<T>
126 where
127 T: FromGValue,
128 {
129 T::from_gvalue(self)
130 }
131
132 pub fn get<'a, T>(&'a self) -> GremlinResult<&'a T>
133 where
134 T: BorrowFromGValue,
135 {
136 T::from_gvalue(self)
137 }
138
139 pub fn is_cardinality(&self) -> bool {
140 match self {
141 GValue::Cardinality(_) => true,
142 _ => false,
143 }
144 }
145}
146
147impl From<Date> for GValue {
148 fn from(val: Date) -> Self {
149 GValue::Date(val)
150 }
151}
152
153impl From<String> for GValue {
154 fn from(val: String) -> Self {
155 GValue::String(val)
156 }
157}
158
159impl From<&String> for GValue {
160 fn from(val: &String) -> Self {
161 GValue::String(val.clone())
162 }
163}
164
165impl From<i32> for GValue {
166 fn from(val: i32) -> Self {
167 GValue::Int32(val)
168 }
169}
170
171impl From<Vec<u8>> for GValue {
172 fn from(val: Vec<u8>) -> Self {
173 GValue::Bytes(val.to_vec())
174 }
175}
176
177impl From<i64> for GValue {
178 fn from(val: i64) -> Self {
179 GValue::Int64(val)
180 }
181}
182
183impl From<f32> for GValue {
184 fn from(val: f32) -> Self {
185 GValue::Float(val)
186 }
187}
188impl From<f64> for GValue {
189 fn from(val: f64) -> Self {
190 GValue::Double(val)
191 }
192}
193
194impl<'a> From<&'a str> for GValue {
195 fn from(val: &'a str) -> Self {
196 GValue::String(String::from(val))
197 }
198}
199
200impl From<Vertex> for GValue {
201 fn from(val: Vertex) -> Self {
202 GValue::Vertex(val)
203 }
204}
205
206impl From<&Vertex> for GValue {
207 fn from(val: &Vertex) -> Self {
208 GValue::Vertex(val.clone())
209 }
210}
211
212impl From<Path> for GValue {
213 fn from(val: Path) -> Self {
214 GValue::Path(val)
215 }
216}
217impl From<Edge> for GValue {
218 fn from(val: Edge) -> Self {
219 GValue::Edge(val)
220 }
221}
222
223impl From<VertexProperty> for GValue {
224 fn from(val: VertexProperty) -> Self {
225 GValue::VertexProperty(val)
226 }
227}
228
229impl From<Traverser> for GValue {
230 fn from(val: Traverser) -> Self {
231 GValue::Traverser(val)
232 }
233}
234impl From<TraversalMetrics> for GValue {
235 fn from(val: TraversalMetrics) -> Self {
236 GValue::TraversalMetrics(val)
237 }
238}
239
240impl From<TraversalExplanation> for GValue {
241 fn from(val: TraversalExplanation) -> Self {
242 GValue::TraversalExplanation(val)
243 }
244}
245
246impl From<Metric> for GValue {
247 fn from(val: Metric) -> Self {
248 GValue::Metric(val)
249 }
250}
251
252impl From<Property> for GValue {
253 fn from(val: Property) -> Self {
254 GValue::Property(val)
255 }
256}
257
258impl From<Scope> for GValue {
259 fn from(val: Scope) -> Self {
260 GValue::Scope(val)
261 }
262}
263
264impl From<Order> for GValue {
265 fn from(val: Order) -> Self {
266 GValue::Order(val)
267 }
268}
269impl From<Token> for GValue {
270 fn from(val: Token) -> Self {
271 GValue::Token(val)
272 }
273}
274
275impl From<HashMap<String, GValue>> for GValue {
276 fn from(val: HashMap<String, GValue>) -> Self {
277 GValue::Map(Map::from(val))
278 }
279}
280
281impl From<HashMap<GKey, GValue>> for GValue {
282 fn from(val: HashMap<GKey, GValue>) -> Self {
283 GValue::Map(Map::from(val))
284 }
285}
286
287impl From<BTreeMap<String, GValue>> for GValue {
288 fn from(val: BTreeMap<String, GValue>) -> Self {
289 GValue::Map(Map::from(val))
290 }
291}
292
293impl From<Vec<GValue>> for GValue {
294 fn from(val: Vec<GValue>) -> Self {
295 GValue::List(List::new(val))
296 }
297}
298
299impl From<GValue> for Vec<GValue> {
300 fn from(val: GValue) -> Self {
301 vec![val]
302 }
303}
304
305impl From<GValue> for VecDeque<GValue> {
306 fn from(val: GValue) -> Self {
307 match val {
308 GValue::List(l) => VecDeque::from(l.take()),
309 GValue::Set(l) => VecDeque::from(l.take()),
310 _ => VecDeque::from(vec![val]),
311 }
312 }
313}
314
315impl From<GKey> for GValue {
316 fn from(val: GKey) -> Self {
317 match val {
318 GKey::String(s) => GValue::String(s),
319 GKey::Token(s) => GValue::String(s.value().clone()),
320 GKey::Vertex(v) => GValue::Vertex(v),
321 GKey::Edge(v) => GValue::Edge(v),
322 }
323 }
324}
325
326impl From<Predicate> for GValue {
327 fn from(val: Predicate) -> GValue {
328 GValue::P(val)
329 }
330}
331
332impl From<TextP> for GValue {
333 fn from(val: TextP) -> GValue {
334 GValue::TextP(val)
335 }
336}
337
338impl From<T> for GValue {
339 fn from(val: T) -> GValue {
340 GValue::T(val)
341 }
342}
343
344impl From<Bytecode> for GValue {
345 fn from(val: Bytecode) -> GValue {
346 GValue::Bytecode(val)
347 }
348}
349
350impl From<bool> for GValue {
351 fn from(val: bool) -> GValue {
352 GValue::Bool(val)
353 }
354}
355
356impl From<LabelType> for GValue {
357 fn from(val: LabelType) -> GValue {
358 match val {
359 LabelType::Str(val) => val.into(),
360 LabelType::Bool(val) => val.into(),
361 LabelType::T(val) => val.into(),
362 }
363 }
364}
365
366impl From<Cardinality> for GValue {
367 fn from(val: Cardinality) -> GValue {
368 GValue::Cardinality(val)
369 }
370}
371
372impl From<uuid::Uuid> for GValue {
373 fn from(val: uuid::Uuid) -> GValue {
374 GValue::Uuid(val)
375 }
376}
377
378impl std::convert::TryFrom<GValue> for String {
379 type Error = crate::GremlinError;
380
381 fn try_from(value: GValue) -> GremlinResult<Self> {
382 match value {
383 GValue::String(s) => Ok(s),
384 GValue::List(s) => from_list(s),
385 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to String", value))),
386 }
387 }
388}
389
390impl std::convert::TryFrom<GValue> for i32 {
391 type Error = crate::GremlinError;
392
393 fn try_from(value: GValue) -> GremlinResult<Self> {
394 match value {
395 GValue::Int32(s) => Ok(s),
396 GValue::List(s) => from_list(s),
397 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to i32", value))),
398 }
399 }
400}
401
402impl std::convert::TryFrom<GValue> for i64 {
403 type Error = crate::GremlinError;
404
405 fn try_from(value: GValue) -> GremlinResult<Self> {
406 match value {
407 GValue::Int64(s) => Ok(s),
408 GValue::List(s) => from_list(s),
409 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to i32", value))),
410 }
411 }
412}
413
414impl std::convert::TryFrom<GValue> for uuid::Uuid {
415 type Error = crate::GremlinError;
416
417 fn try_from(value: GValue) -> GremlinResult<Self> {
418 match value {
419 GValue::Uuid(uid) => Ok(uid),
420 GValue::List(s) => from_list(s),
421 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to Uuid", value))),
422 }
423 }
424}
425
426impl std::convert::TryFrom<GValue> for Date {
427 type Error = crate::GremlinError;
428
429 fn try_from(value: GValue) -> GremlinResult<Self> {
430 match value {
431 GValue::Date(date) => Ok(date),
432 GValue::List(s) => from_list(s),
433 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to DateTime<Utc>", value))),
434 }
435 }
436}
437
438impl std::convert::TryFrom<GValue> for bool {
439 type Error = crate::GremlinError;
440
441 fn try_from(value: GValue) -> GremlinResult<Self> {
442 match value {
443 GValue::Bool(val) => Ok(val),
444 GValue::List(s) => from_list(s),
445 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to bool", value))),
446 }
447 }
448}
449
450impl std::convert::TryFrom<GValue> for f32 {
451 type Error = crate::GremlinError;
452
453 fn try_from(value: GValue) -> GremlinResult<Self> {
454 match value {
455 GValue::Float(x) => Ok(x),
456 GValue::List(s) => from_list(s),
457 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to f32", value))),
458 }
459 }
460}
461
462impl std::convert::TryFrom<GValue> for f64 {
463 type Error = crate::GremlinError;
464
465 fn try_from(value: GValue) -> GremlinResult<Self> {
466 match value {
467 GValue::Double(x) => Ok(x),
468 GValue::List(s) => from_list(s),
469 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to f64", value))),
470 }
471 }
472}
473
474impl std::convert::TryFrom<GValue> for BTreeMap<String, GValue> {
475 type Error = crate::GremlinError;
476
477 fn try_from(value: GValue) -> GremlinResult<Self> {
478 if let GValue::Map(m) = value {
479 m.try_into()
480 } else {
481 Err(GremlinError::Cast(format!("Cannot cast {:?} to HashMap<GKey, GValue>", value)))
482 }
483 }
484}
485
486impl std::convert::TryFrom<GValue> for HashMap<GKey, GValue> {
487 type Error = crate::GremlinError;
488
489 fn try_from(value: GValue) -> GremlinResult<Self> {
490 if let GValue::Map(m) = value {
491 Ok(m.into())
492 } else {
493 Err(GremlinError::Cast(format!("Cannot cast {:?} to HashMap<GKey, GValue>", value)))
494 }
495 }
496}
497
498impl std::convert::TryFrom<GValue> for HashMap<String, GValue> {
499 type Error = crate::GremlinError;
500
501 fn try_from(value: GValue) -> GremlinResult<Self> {
502 if let GValue::Map(m) = value {
503 m.try_into()
504 } else {
505 Err(GremlinError::Cast(format!("Cannot cast {:?} to HashMap<GKey, GValue>", value)))
506 }
507 }
508}
509
510fn from_list<T>(glist: List) -> GremlinResult<T>
511where
512 T: std::convert::TryFrom<GValue, Error = GremlinError>,
513{
514 let mut vec = glist.take();
515
516 match vec.len() {
517 1 => vec.pop().unwrap().try_into(),
518 _ => Err(GremlinError::Cast(String::from("Cannot cast a List to String"))),
519 }
520}
521
522macro_rules! impl_try_from_option {
525 ($t:ty) => {
526 impl std::convert::TryFrom<GValue> for Option<$t> {
527 type Error = crate::GremlinError;
528
529 fn try_from(value: GValue) -> GremlinResult<Self> {
530 if let GValue::Null = value {
531 return Ok(None);
532 }
533 let res: $t = value.try_into()?;
534 Ok(Some(res))
535 }
536 }
537 };
538}
539
540impl_try_from_option!(String);
541impl_try_from_option!(i32);
542impl_try_from_option!(i64);
543impl_try_from_option!(f32);
544impl_try_from_option!(f64);
545impl_try_from_option!(Date);
546impl_try_from_option!(uuid::Uuid);
547impl_try_from_option!(bool);
548
549fn for_list<T>(glist: &List) -> GremlinResult<Vec<T>>
550where
551 T: std::convert::TryFrom<GValue, Error = GremlinError>,
552{
553 glist.iter().map(|x| x.clone().try_into()).collect::<GremlinResult<Vec<T>>>()
554}
555
556fn for_list_to_set<T>(glist: &List) -> GremlinResult<HashSet<T>>
557where
558 T: std::convert::TryFrom<GValue, Error = GremlinError> + Hash + Eq,
559{
560 glist.iter().map(|x| x.clone().try_into()).collect::<GremlinResult<HashSet<T>>>()
561}
562
563fn for_set<T>(gset: &Set) -> GremlinResult<HashSet<T>>
564where
565 T: std::convert::TryFrom<GValue, Error = GremlinError> + Hash + Eq,
566{
567 gset.iter().map(|x| x.clone().try_into()).collect::<GremlinResult<HashSet<T>>>()
568}
569
570macro_rules! impl_try_from_set {
571 ($t:ty) => {
572 impl FromGValue for HashSet<$t> {
575 fn from_gvalue(value: GValue) -> GremlinResult<Self> {
576 match value {
577 GValue::List(s) => for_list_to_set(&s),
578 GValue::Set(s) => for_set(&s),
579 GValue::Null => Ok(HashSet::new()),
580 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to HashSet", value))),
581 }
582 }
583 }
584
585 impl std::convert::TryFrom<GValue> for HashSet<$t> {
586 type Error = crate::GremlinError;
587
588 fn try_from(value: GValue) -> GremlinResult<Self> {
589 match value {
590 GValue::List(s) => for_list_to_set(&s),
591 GValue::Set(s) => for_set(&s),
592 GValue::Null => Ok(HashSet::new()),
593 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to HashSet", value))),
594 }
595 }
596 }
597
598 impl std::convert::TryFrom<&GValue> for HashSet<$t> {
599 type Error = crate::GremlinError;
600
601 fn try_from(value: &GValue) -> GremlinResult<Self> {
602 match value {
603 GValue::List(s) => for_list_to_set(s),
604 GValue::Set(s) => for_set(s),
605 GValue::Null => Ok(HashSet::new()),
606 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to HashSet", value))),
607 }
608 }
609 }
610 };
611}
612
613impl_try_from_set!(String);
614impl_try_from_set!(i32);
615impl_try_from_set!(i64);
616impl_try_from_set!(Date);
617impl_try_from_set!(uuid::Uuid);
618impl_try_from_set!(bool);
619macro_rules! impl_try_from_list {
624 ($t:ty) => {
625 impl std::convert::TryFrom<GValue> for Vec<$t> {
626 type Error = crate::GremlinError;
627
628 fn try_from(value: GValue) -> GremlinResult<Self> {
629 match value {
630 GValue::List(s) => for_list(&s),
631 GValue::Null => Ok(Vec::new()),
632 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to Vec", value))),
633 }
634 }
635 }
636
637 impl std::convert::TryFrom<&GValue> for Vec<$t> {
638 type Error = crate::GremlinError;
639
640 fn try_from(value: &GValue) -> GremlinResult<Self> {
641 match value {
642 GValue::List(s) => for_list(s),
643 GValue::Null => Ok(Vec::new()),
644 _ => Err(GremlinError::Cast(format!("Cannot cast {:?} to Vec", value))),
645 }
646 }
647 }
648 };
649}
650
651impl_try_from_list!(String);
652impl_try_from_list!(i32);
653impl_try_from_list!(i64);
654impl_try_from_list!(f32);
655impl_try_from_list!(f64);
656impl_try_from_list!(Date);
657impl_try_from_list!(uuid::Uuid);
658impl_try_from_list!(bool);