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