gqlite 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gqliterb/.cargo/config.toml +2 -0
  3. data/ext/gqliterb/Cargo.lock +133 -123
  4. data/ext/gqliterb/Cargo.toml +3 -6
  5. data/ext/gqliterb/src/lib.rs +2 -2
  6. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2060 -0
  7. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +132 -0
  8. data/ext/gqliterb/vendor/gqlitedb/askama.toml +3 -0
  9. data/ext/gqliterb/vendor/gqlitedb/benches/common/mod.rs +25 -0
  10. data/ext/gqliterb/vendor/gqlitedb/benches/common/pokec.rs +185 -0
  11. data/ext/gqliterb/vendor/gqlitedb/benches/pokec_divan.rs +137 -0
  12. data/ext/gqliterb/vendor/gqlitedb/benches/pokec_iai.rs +122 -0
  13. data/ext/gqliterb/vendor/gqlitedb/release.toml +7 -0
  14. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/arithmetic.rs +96 -0
  15. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/containers.rs +33 -0
  16. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/count.rs +35 -0
  17. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/stats.rs +168 -0
  18. data/ext/gqliterb/vendor/gqlitedb/src/aggregators.rs +74 -0
  19. data/ext/gqliterb/vendor/gqlitedb/src/capi.rs +236 -0
  20. data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +427 -0
  21. data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +620 -0
  22. data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1106 -0
  23. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +208 -0
  24. data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
  25. data/ext/gqliterb/vendor/gqlitedb/src/error.rs +621 -0
  26. data/ext/gqliterb/vendor/gqlitedb/src/functions/containers.rs +115 -0
  27. data/ext/gqliterb/vendor/gqlitedb/src/functions/edge.rs +20 -0
  28. data/ext/gqliterb/vendor/gqlitedb/src/functions/math.rs +44 -0
  29. data/ext/gqliterb/vendor/gqlitedb/src/functions/node.rs +16 -0
  30. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +48 -0
  31. data/ext/gqliterb/vendor/gqlitedb/src/functions/scalar.rs +86 -0
  32. data/ext/gqliterb/vendor/gqlitedb/src/functions/string.rs +28 -0
  33. data/ext/gqliterb/vendor/gqlitedb/src/functions/value.rs +99 -0
  34. data/ext/gqliterb/vendor/gqlitedb/src/functions.rs +412 -0
  35. data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +268 -0
  36. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1788 -0
  37. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +262 -0
  38. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
  39. data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +42 -0
  40. data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +625 -0
  41. data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +191 -0
  42. data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1153 -0
  43. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +4 -0
  44. data/ext/gqliterb/vendor/gqlitedb/src/prelude.rs +8 -0
  45. data/ext/gqliterb/vendor/gqlitedb/src/serialize_with.rs +94 -0
  46. data/ext/gqliterb/vendor/gqlitedb/src/store/pgql.rs +121 -0
  47. data/ext/gqliterb/vendor/gqlitedb/src/store/redb.rs +1250 -0
  48. data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +994 -0
  49. data/ext/gqliterb/vendor/gqlitedb/src/store.rs +432 -0
  50. data/ext/gqliterb/vendor/gqlitedb/src/tests/compiler.rs +92 -0
  51. data/ext/gqliterb/vendor/gqlitedb/src/tests/evaluators.rs +227 -0
  52. data/ext/gqliterb/vendor/gqlitedb/src/tests/parser.rs +81 -0
  53. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/redb.rs +39 -0
  54. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +39 -0
  55. data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +462 -0
  56. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/ast.rs +356 -0
  57. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/programs.rs +455 -0
  58. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates.rs +2 -0
  59. data/ext/gqliterb/vendor/gqlitedb/src/tests.rs +39 -0
  60. data/ext/gqliterb/vendor/gqlitedb/src/utils.rs +28 -0
  61. data/ext/gqliterb/vendor/gqlitedb/src/value/compare.rs +212 -0
  62. data/ext/gqliterb/vendor/gqlitedb/src/value/contains.rs +47 -0
  63. data/ext/gqliterb/vendor/gqlitedb/src/value/value_map.rs +298 -0
  64. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +559 -0
  65. data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +616 -0
  66. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/call_stats.sql +22 -0
  67. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_count_for_node.sql +3 -0
  68. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_create.sql +6 -0
  69. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete.sql +1 -0
  70. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete_by_nodes.sql +2 -0
  71. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_select.sql +139 -0
  72. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_update.sql +4 -0
  73. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_create.sql +16 -0
  74. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_delete.sql +3 -0
  75. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_create_table.sql +1 -0
  76. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_get.sql +1 -0
  77. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_set.sql +1 -0
  78. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_create.sql +1 -0
  79. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_delete.sql +1 -0
  80. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_select.sql +42 -0
  81. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_update.sql +4 -0
  82. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/table_exists.sql +5 -0
  83. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_from_1_01.sql +2 -0
  84. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_graph_from_1_01.sql +65 -0
  85. metadata +82 -2
@@ -0,0 +1,559 @@
1
+ use serde::{Deserialize, Serialize};
2
+ use std::{
3
+ hash::Hash,
4
+ ops::{Add, Div, Mul, Neg, Rem, Sub},
5
+ };
6
+
7
+ use crate::prelude::*;
8
+
9
+ mod compare;
10
+ mod contains;
11
+ mod value_map;
12
+
13
+ pub(crate) use compare::{compare, Ordering};
14
+ pub(crate) use contains::{contains, ContainResult};
15
+ pub use value_map::ValueMap;
16
+
17
+ /// Represent a value in a properties for a Node or an Edge.
18
+ #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
19
+ #[serde(untagged)]
20
+ pub enum Value
21
+ {
22
+ /// Null value.
23
+ #[default]
24
+ Null,
25
+ /// Boolean value.
26
+ Boolean(bool),
27
+ /// Signed integer value.
28
+ Integer(i64),
29
+ #[serde(
30
+ serialize_with = "serialize_with::serialize_float",
31
+ deserialize_with = "serialize_with::deserialize_float"
32
+ )]
33
+ /// Floating point value.
34
+ Float(f64),
35
+ /// String value.
36
+ String(String),
37
+ /// Array of values.
38
+ Array(Vec<Value>),
39
+ /// Unordered map of values.
40
+ Map(ValueMap),
41
+ /// A node in the graph.
42
+ Node(graph::Node),
43
+ /// An edge in the graph.
44
+ Edge(graph::Edge),
45
+ /// A path in the graph.
46
+ Path(graph::Path),
47
+ }
48
+
49
+ impl Value
50
+ {
51
+ pub(crate) fn is_null(&self) -> bool
52
+ {
53
+ match self
54
+ {
55
+ Value::Null => true,
56
+ _ => false,
57
+ }
58
+ }
59
+ pub(crate) fn remove_null(self) -> Self
60
+ {
61
+ match self
62
+ {
63
+ Value::Map(object) => object.remove_null().into(),
64
+ o => o,
65
+ }
66
+ }
67
+ /// Transform this value into a map. This function is guaranteed to succeed,
68
+ /// in case the value does not contains a map, it will create a default empty
69
+ /// map.
70
+ pub fn into_map(self) -> ValueMap
71
+ {
72
+ match self
73
+ {
74
+ Value::Map(o) => o.clone(),
75
+ _ => ValueMap::new(),
76
+ }
77
+ }
78
+ pub(crate) fn access<'a>(&self, mut path: impl Iterator<Item = &'a String>) -> Value
79
+ {
80
+ match path.next()
81
+ {
82
+ Some(name) => match self
83
+ {
84
+ Value::Node(node) => match node.properties.get(name)
85
+ {
86
+ Some(val) => val.access(path),
87
+ None => Value::Null,
88
+ },
89
+ Value::Edge(edge) => match edge.properties.get(name)
90
+ {
91
+ Some(val) => val.access(path),
92
+ None => Value::Null,
93
+ },
94
+ Value::Map(obj) => match obj.get(name)
95
+ {
96
+ Some(val) => val.access(path),
97
+ None => Value::Null,
98
+ },
99
+ _ => Value::Null,
100
+ },
101
+ None => self.to_owned(),
102
+ }
103
+ }
104
+ pub(crate) fn compare(&self, rhs: &Value) -> crate::value::Ordering
105
+ {
106
+ crate::value::compare(self, rhs)
107
+ }
108
+
109
+ fn orderability_map(lhs: &ValueMap, rhs: &ValueMap) -> std::cmp::Ordering
110
+ {
111
+ let o = lhs.len().cmp(&rhs.len());
112
+ match o
113
+ {
114
+ std::cmp::Ordering::Equal => lhs
115
+ .iter()
116
+ .map(|(key, value)| value.orderability(rhs.get(key).unwrap_or(&Value::Null)))
117
+ .find(|p| *p != std::cmp::Ordering::Equal)
118
+ .unwrap_or(std::cmp::Ordering::Equal),
119
+ o => o,
120
+ }
121
+ }
122
+ fn orderability_float(lhs: &f64, rhs: &f64) -> std::cmp::Ordering
123
+ {
124
+ if lhs.is_nan()
125
+ {
126
+ if rhs.is_nan()
127
+ {
128
+ std::cmp::Ordering::Equal
129
+ }
130
+ else
131
+ {
132
+ std::cmp::Ordering::Greater
133
+ }
134
+ }
135
+ else if rhs.is_nan()
136
+ {
137
+ std::cmp::Ordering::Less
138
+ }
139
+ else
140
+ {
141
+ lhs.total_cmp(rhs)
142
+ }
143
+ }
144
+ /// Compute the order between self and rhs, for OrderBy, according to the OpenCypher specification.
145
+ /// This order is total.
146
+ pub(crate) fn orderability(&self, rhs: &Value) -> std::cmp::Ordering
147
+ {
148
+ match self
149
+ {
150
+ Value::Null => match rhs
151
+ {
152
+ Value::Null => std::cmp::Ordering::Equal,
153
+ _ => std::cmp::Ordering::Greater,
154
+ },
155
+ Value::Integer(lhs) => match rhs
156
+ {
157
+ Value::Null => std::cmp::Ordering::Less,
158
+ Value::Integer(rhs) => lhs.cmp(rhs),
159
+ Value::Float(rhs) => Self::orderability_float(&(*lhs as f64), rhs),
160
+ _ => std::cmp::Ordering::Greater,
161
+ },
162
+ Value::Float(lhs) => match rhs
163
+ {
164
+ Value::Null => std::cmp::Ordering::Less,
165
+ Value::Integer(rhs) => Self::orderability_float(lhs, &(*rhs as f64)),
166
+ Value::Float(rhs) => Self::orderability_float(lhs, rhs),
167
+ _ => std::cmp::Ordering::Greater,
168
+ },
169
+ Value::Boolean(lhs) => match rhs
170
+ {
171
+ Value::Null | Value::Integer(..) | Value::Float(..) => std::cmp::Ordering::Less,
172
+ Value::Boolean(rhs) => lhs.cmp(rhs),
173
+ _ => std::cmp::Ordering::Greater,
174
+ },
175
+ Value::String(lhs) => match rhs
176
+ {
177
+ Value::Null | Value::Integer(..) | Value::Float(..) | Value::Boolean(..) =>
178
+ {
179
+ std::cmp::Ordering::Less
180
+ }
181
+ Value::String(rhs) => lhs.cmp(rhs),
182
+ _ => std::cmp::Ordering::Greater,
183
+ },
184
+ Value::Path(lhs) => match rhs
185
+ {
186
+ Value::Null
187
+ | Value::Integer(..)
188
+ | Value::Float(..)
189
+ | Value::Boolean(..)
190
+ | Value::String(..) => std::cmp::Ordering::Less,
191
+ Value::Path(rhs) =>
192
+ {
193
+ match Self::orderability_map(&lhs.source.properties, &rhs.source.properties)
194
+ {
195
+ std::cmp::Ordering::Equal =>
196
+ {
197
+ match Self::orderability_map(&lhs.properties, &rhs.properties)
198
+ {
199
+ std::cmp::Ordering::Equal =>
200
+ {
201
+ Self::orderability_map(&lhs.destination.properties, &rhs.destination.properties)
202
+ }
203
+ o => o,
204
+ }
205
+ }
206
+ o => o,
207
+ }
208
+ }
209
+ _ => std::cmp::Ordering::Greater,
210
+ },
211
+ Value::Array(lhs) => match rhs
212
+ {
213
+ Value::Null
214
+ | Value::Integer(..)
215
+ | Value::Float(..)
216
+ | Value::Boolean(..)
217
+ | Value::String(..)
218
+ | Value::Path(..) => std::cmp::Ordering::Less,
219
+ Value::Array(rhs) => lhs
220
+ .iter()
221
+ .zip(rhs.iter())
222
+ .map(|(lhs, rhs)| Self::orderability(lhs, rhs))
223
+ .find(|p| *p != std::cmp::Ordering::Equal)
224
+ .unwrap_or(lhs.len().cmp(&rhs.len())),
225
+ _ => std::cmp::Ordering::Greater,
226
+ },
227
+ Value::Edge(lhs) => match rhs
228
+ {
229
+ Value::Null
230
+ | Value::Integer(..)
231
+ | Value::Float(..)
232
+ | Value::Boolean(..)
233
+ | Value::String(..)
234
+ | Value::Path(..)
235
+ | Value::Array(..) => std::cmp::Ordering::Less,
236
+ Value::Edge(rhs) => Self::orderability_map(&lhs.properties, &rhs.properties),
237
+ _ => std::cmp::Ordering::Greater,
238
+ },
239
+ Value::Node(lhs) => match rhs
240
+ {
241
+ Value::Null
242
+ | Value::Integer(..)
243
+ | Value::Float(..)
244
+ | Value::Boolean(..)
245
+ | Value::String(..)
246
+ | Value::Path(..)
247
+ | Value::Array(..)
248
+ | Value::Edge(..) => std::cmp::Ordering::Less,
249
+ Value::Node(rhs) => Self::orderability_map(&lhs.properties, &rhs.properties),
250
+ _ => std::cmp::Ordering::Greater,
251
+ },
252
+ Value::Map(lhs) => match rhs
253
+ {
254
+ Value::Null
255
+ | Value::Integer(..)
256
+ | Value::Float(..)
257
+ | Value::Boolean(..)
258
+ | Value::String(..)
259
+ | Value::Path(..)
260
+ | Value::Array(..)
261
+ | Value::Edge(..)
262
+ | Value::Node(..) => std::cmp::Ordering::Less,
263
+ Value::Map(rhs) => Self::orderability_map(lhs, rhs),
264
+ },
265
+ }
266
+ }
267
+ }
268
+
269
+ impl Hash for Value
270
+ {
271
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H)
272
+ {
273
+ match self
274
+ {
275
+ Value::Null =>
276
+ {}
277
+ Value::Boolean(b) => b.hash(state),
278
+ Value::Integer(i) => i.hash(state),
279
+ Value::Float(f) =>
280
+ {
281
+ let bits = if f.is_nan()
282
+ {
283
+ 0x7ff8000000000000
284
+ }
285
+ else
286
+ {
287
+ f.to_bits()
288
+ };
289
+ bits.hash(state);
290
+ }
291
+ Value::String(s) => s.hash(state),
292
+ Value::Array(a) => a.hash(state),
293
+ Value::Map(m) => m.hash(state),
294
+ Value::Node(n) => n.hash(state),
295
+ Value::Edge(e) => e.hash(state),
296
+ Value::Path(p) => p.hash(state),
297
+ }
298
+ }
299
+ }
300
+
301
+ impl Add for Value
302
+ {
303
+ type Output = crate::Result<Value>;
304
+ fn add(self, rhs: Self) -> Self::Output
305
+ {
306
+ match self
307
+ {
308
+ Value::Boolean(..) | Value::Node(..) | Value::Edge(..) | Value::Map(..) | Value::Path(..) =>
309
+ {
310
+ Err(RunTimeError::InvalidBinaryOperands.into())
311
+ }
312
+ Value::Null => Ok(Value::Null),
313
+ Self::Array(lhs) => match rhs
314
+ {
315
+ Self::Array(rhs) =>
316
+ {
317
+ let mut lhs = lhs.clone();
318
+ lhs.append(&mut rhs.clone());
319
+ Ok(lhs.into())
320
+ }
321
+ _ =>
322
+ {
323
+ let mut lhs = lhs.clone();
324
+ lhs.push(rhs.clone());
325
+ Ok(lhs.into())
326
+ }
327
+ },
328
+ Self::Float(lhs) => match rhs
329
+ {
330
+ Self::Float(rhs) => Ok((lhs + rhs).into()),
331
+ Self::Integer(rhs) => Ok((lhs + rhs as f64).into()),
332
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
333
+ },
334
+ Self::Integer(lhs) => match rhs
335
+ {
336
+ Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
337
+ Self::Integer(rhs) => Ok((lhs + rhs).into()),
338
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
339
+ },
340
+ Self::String(lhs) => match rhs
341
+ {
342
+ Self::String(rhs) => Ok((lhs + &rhs).into()),
343
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
344
+ },
345
+ }
346
+ }
347
+ }
348
+
349
+ macro_rules! impl_mdsr {
350
+ ($x:tt, $op:tt) => {
351
+ impl $x for Value
352
+ {
353
+ type Output = crate::Result<Value>;
354
+ fn $op(self, rhs: Self) -> Self::Output
355
+ {
356
+ match self
357
+ {
358
+ Value::Boolean(..)
359
+ | Value::String(..)
360
+ | Value::Node(..)
361
+ | Value::Edge(..)
362
+ | Value::Array(..)
363
+ | Value::Map(..)
364
+ | Value::Path(..) => Err(RunTimeError::InvalidBinaryOperands.into()),
365
+ Value::Null => Ok(Value::Null),
366
+ Self::Float(lhs) => match rhs
367
+ {
368
+ Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
369
+ Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
370
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
371
+ },
372
+ Self::Integer(lhs) => match rhs
373
+ {
374
+ Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
375
+ Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
376
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
377
+ },
378
+ }
379
+ }
380
+ }
381
+ };
382
+ }
383
+
384
+ impl_mdsr!(Mul, mul);
385
+ impl_mdsr!(Sub, sub);
386
+ impl_mdsr!(Div, div);
387
+ impl_mdsr!(Rem, rem);
388
+
389
+ impl Neg for Value
390
+ {
391
+ type Output = crate::Result<Value>;
392
+ fn neg(self) -> Self::Output
393
+ {
394
+ match self
395
+ {
396
+ Self::Float(fl) => Ok((-fl).into()),
397
+ Self::Integer(i) => Ok((-i).into()),
398
+ Value::Null => Ok(Value::Null),
399
+ Value::Boolean(..)
400
+ | Value::String(..)
401
+ | Value::Node(..)
402
+ | Value::Edge(..)
403
+ | Value::Array(..)
404
+ | Value::Map(..)
405
+ | Value::Path(..) => Err(RunTimeError::InvalidNegationOperands.into()),
406
+ }
407
+ }
408
+ }
409
+
410
+ impl std::fmt::Display for Value
411
+ {
412
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
413
+ {
414
+ match self
415
+ {
416
+ Value::Null => write!(f, "null"),
417
+ Value::Boolean(b) => write!(f, "{}", b),
418
+ Value::Integer(i) => write!(f, "{}", i),
419
+ Value::Float(fl) => write!(f, "{}", fl),
420
+ Value::String(s) => write!(f, "{}", s),
421
+ Value::Array(v) => write!(
422
+ f,
423
+ "[{}]",
424
+ v.iter()
425
+ .map(|x| x.to_string())
426
+ .collect::<Vec<String>>()
427
+ .join(", ")
428
+ ),
429
+ Value::Map(o) => write!(f, "{}", o),
430
+ Value::Node(n) => write!(f, "{}", n),
431
+ Value::Edge(e) => write!(f, "{}", e),
432
+ Value::Path(p) => write!(f, "{}", p),
433
+ }
434
+ }
435
+ }
436
+
437
+ /// Trait to return a reference to the underlying type
438
+ pub(crate) trait ValueTryIntoRef<T>
439
+ {
440
+ /// Return a reference to T
441
+ fn try_into_ref<'a>(&'a self) -> Result<&'a T, Error>;
442
+ }
443
+
444
+ impl ValueTryIntoRef<Value> for Value
445
+ {
446
+ fn try_into_ref<'a>(&'a self) -> Result<&'a Value, Error>
447
+ {
448
+ Ok(self)
449
+ }
450
+ }
451
+
452
+ macro_rules! impl_to_value {
453
+ ($type:ty, $vn:tt) => {
454
+ impl Into<Value> for $type
455
+ {
456
+ fn into(self) -> Value
457
+ {
458
+ Value::$vn(self.clone())
459
+ }
460
+ }
461
+
462
+ impl Into<Value> for Vec<$type>
463
+ {
464
+ fn into(self) -> Value
465
+ {
466
+ Value::Array(self.into_iter().map(|v| v.into()).collect())
467
+ }
468
+ }
469
+ impl TryInto<$type> for Value
470
+ {
471
+ type Error = ErrorType;
472
+ fn try_into(self) -> Result<$type, Self::Error>
473
+ {
474
+ match self
475
+ {
476
+ Value::$vn(v) => Ok(v),
477
+ _ => Err(
478
+ InternalError::InvalidValueCast {
479
+ value: self,
480
+ typename: stringify!($type),
481
+ }
482
+ .into(),
483
+ ),
484
+ }
485
+ }
486
+ }
487
+
488
+ impl ValueTryIntoRef<$type> for Value
489
+ {
490
+ fn try_into_ref<'a>(&'a self) -> Result<&'a $type, Error>
491
+ {
492
+ match self
493
+ {
494
+ Value::$vn(v) => Ok(v),
495
+ _ => Err(
496
+ InternalError::InvalidValueCast {
497
+ value: self.clone(),
498
+ typename: stringify!($type),
499
+ }
500
+ .into(),
501
+ ),
502
+ }
503
+ }
504
+ }
505
+ };
506
+ }
507
+
508
+ impl_to_value!(bool, Boolean);
509
+ impl_to_value!(i64, Integer);
510
+ impl_to_value!(f64, Float);
511
+ impl_to_value!(String, String);
512
+ impl_to_value!(graph::Node, Node);
513
+ impl_to_value!(graph::Edge, Edge);
514
+ impl_to_value!(Vec<Value>, Array);
515
+ impl_to_value!(ValueMap, Map);
516
+
517
+ impl Into<Value> for &str
518
+ {
519
+ fn into(self) -> Value
520
+ {
521
+ Value::String(self.into())
522
+ }
523
+ }
524
+
525
+ #[cfg(test)]
526
+ macro_rules! array {
527
+ () => (
528
+ $crate::value::Value::Array(Default::default())
529
+ );
530
+ ($($x:expr),+ $(,)?) => (
531
+ $crate::value::Value::Array(
532
+ vec![$($x.into()),+]
533
+ )
534
+ );
535
+ }
536
+
537
+ #[cfg(test)]
538
+ pub(crate) use array;
539
+
540
+ /// Convenient macro for creating ValueMap.
541
+ ///
542
+ /// Example:
543
+ ///
544
+ /// ```rust
545
+ /// # use gqlitedb::{ValueMap, map};
546
+ /// let value_map: ValueMap = map!("hello" => 12);
547
+ /// ```
548
+ #[macro_export]
549
+ macro_rules! map {
550
+ // map-like
551
+ ($($k:expr => $v:expr),* $(,)?) => {
552
+ {
553
+ core::convert::From::from([$(($k.to_string(), $v.into()),)*])
554
+ }
555
+ };
556
+ }
557
+
558
+ #[cfg(test)]
559
+ pub(crate) use map;