gqlite 1.2.0 → 1.2.3

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 +152 -135
  4. data/ext/gqliterb/Cargo.toml +4 -6
  5. data/ext/gqliterb/src/lib.rs +8 -2
  6. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2115 -0
  7. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +138 -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 +259 -0
  20. data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +431 -0
  21. data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +621 -0
  22. data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1115 -0
  23. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +342 -0
  24. data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
  25. data/ext/gqliterb/vendor/gqlitedb/src/error.rs +613 -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 +80 -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 +410 -0
  35. data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +283 -0
  36. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1776 -0
  37. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +267 -0
  38. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
  39. data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +41 -0
  40. data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +611 -0
  41. data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +196 -0
  42. data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1183 -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 +1262 -0
  48. data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +1026 -0
  49. data/ext/gqliterb/vendor/gqlitedb/src/store.rs +439 -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 +46 -0
  54. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +46 -0
  55. data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +470 -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 +609 -0
  65. data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +610 -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,609 @@
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
+ Self::Null => Ok(Self::Null),
333
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
334
+ },
335
+ Self::Integer(lhs) => match rhs
336
+ {
337
+ Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
338
+ Self::Integer(rhs) => Ok((lhs + rhs).into()),
339
+ Self::Null => Ok(Self::Null),
340
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
341
+ },
342
+ Self::String(lhs) => match rhs
343
+ {
344
+ Self::String(rhs) => Ok((lhs + &rhs).into()),
345
+ Self::Null => Ok(Self::Null),
346
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
347
+ },
348
+ }
349
+ }
350
+ }
351
+
352
+ macro_rules! impl_mdsr {
353
+ ($x:tt, $op:tt) => {
354
+ impl $x for Value
355
+ {
356
+ type Output = crate::Result<Value>;
357
+ fn $op(self, rhs: Self) -> Self::Output
358
+ {
359
+ match self
360
+ {
361
+ Value::Boolean(..)
362
+ | Value::String(..)
363
+ | Value::Node(..)
364
+ | Value::Edge(..)
365
+ | Value::Array(..)
366
+ | Value::Map(..)
367
+ | Value::Path(..) => Err(RunTimeError::InvalidBinaryOperands.into()),
368
+ Value::Null => Ok(Value::Null),
369
+ Self::Float(lhs) => match rhs
370
+ {
371
+ Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
372
+ Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
373
+ Self::Null => Ok(Self::Null),
374
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
375
+ },
376
+ Self::Integer(lhs) => match rhs
377
+ {
378
+ Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
379
+ Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
380
+ Self::Null => Ok(Self::Null),
381
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
382
+ },
383
+ }
384
+ }
385
+ }
386
+ };
387
+ }
388
+
389
+ impl_mdsr!(Mul, mul);
390
+ impl_mdsr!(Sub, sub);
391
+ impl_mdsr!(Div, div);
392
+ impl_mdsr!(Rem, rem);
393
+
394
+ impl Value
395
+ {
396
+ pub(crate) fn pow(self, rhs: Value) -> Result<Value>
397
+ {
398
+ match self
399
+ {
400
+ Value::Boolean(..)
401
+ | Value::String(..)
402
+ | Value::Node(..)
403
+ | Value::Edge(..)
404
+ | Value::Array(..)
405
+ | Value::Map(..)
406
+ | Value::Path(..) => Err(RunTimeError::InvalidBinaryOperands.into()),
407
+ Value::Null => Ok(Value::Null),
408
+ Self::Float(lhs) => match rhs
409
+ {
410
+ Self::Float(rhs) => Ok(lhs.powf(rhs).into()),
411
+ Self::Integer(rhs) => Ok(lhs.powf(rhs as f64).into()),
412
+ Self::Null => Ok(Self::Null),
413
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
414
+ },
415
+ Self::Integer(lhs) => match rhs
416
+ {
417
+ Self::Float(rhs) => Ok((lhs as f64).powf(rhs).into()),
418
+ Self::Integer(rhs) => match rhs.try_into()
419
+ {
420
+ Ok(rhs) => Ok(lhs.pow(rhs).into()),
421
+ Err(_) => Ok((lhs as f64).powf(rhs as f64).into()),
422
+ },
423
+ Self::Null => Ok(Self::Null),
424
+ _ => Err(RunTimeError::InvalidBinaryOperands.into()),
425
+ },
426
+ }
427
+ }
428
+ }
429
+
430
+ impl Neg for Value
431
+ {
432
+ type Output = crate::Result<Value>;
433
+ fn neg(self) -> Self::Output
434
+ {
435
+ match self
436
+ {
437
+ Self::Float(fl) => Ok((-fl).into()),
438
+ Self::Integer(i) => Ok((-i).into()),
439
+ Value::Null => Ok(Value::Null),
440
+ Value::Boolean(..)
441
+ | Value::String(..)
442
+ | Value::Node(..)
443
+ | Value::Edge(..)
444
+ | Value::Array(..)
445
+ | Value::Map(..)
446
+ | Value::Path(..) => Err(RunTimeError::InvalidNegationOperands.into()),
447
+ }
448
+ }
449
+ }
450
+
451
+ impl std::fmt::Display for Value
452
+ {
453
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
454
+ {
455
+ match self
456
+ {
457
+ Value::Null => write!(f, "null"),
458
+ Value::Boolean(b) => write!(f, "{}", b),
459
+ Value::Integer(i) => write!(f, "{}", i),
460
+ Value::Float(fl) => write!(f, "{}", fl),
461
+ Value::String(s) => write!(f, "{}", s),
462
+ Value::Array(v) => write!(
463
+ f,
464
+ "[{}]",
465
+ v.iter()
466
+ .map(|x| x.to_string())
467
+ .collect::<Vec<String>>()
468
+ .join(", ")
469
+ ),
470
+ Value::Map(o) => write!(f, "{}", o),
471
+ Value::Node(n) => write!(f, "{}", n),
472
+ Value::Edge(e) => write!(f, "{}", e),
473
+ Value::Path(p) => write!(f, "{}", p),
474
+ }
475
+ }
476
+ }
477
+
478
+ /// Trait to return a reference to the underlying type
479
+ pub trait ValueTryIntoRef<T>
480
+ {
481
+ /// Return a reference to T
482
+ fn try_into_ref<'a>(&'a self) -> Result<&'a T, Error>;
483
+ }
484
+
485
+ impl ValueTryIntoRef<Value> for Value
486
+ {
487
+ fn try_into_ref<'a>(&'a self) -> Result<&'a Value, Error>
488
+ {
489
+ Ok(self)
490
+ }
491
+ }
492
+
493
+ macro_rules! impl_to_value {
494
+ ($type:ty, $vn:tt) => {
495
+ impl Into<Value> for $type
496
+ {
497
+ fn into(self) -> Value
498
+ {
499
+ Value::$vn(self.clone())
500
+ }
501
+ }
502
+
503
+ impl Into<Value> for Vec<$type>
504
+ {
505
+ fn into(self) -> Value
506
+ {
507
+ Value::Array(self.into_iter().map(|v| v.into()).collect())
508
+ }
509
+ }
510
+ impl TryInto<$type> for Value
511
+ {
512
+ type Error = ErrorType;
513
+ fn try_into(self) -> Result<$type, Self::Error>
514
+ {
515
+ match self
516
+ {
517
+ Value::$vn(v) => Ok(v),
518
+ _ => Err(
519
+ InternalError::InvalidValueCast {
520
+ value: self,
521
+ typename: stringify!($type),
522
+ }
523
+ .into(),
524
+ ),
525
+ }
526
+ }
527
+ }
528
+
529
+ impl ValueTryIntoRef<$type> for Value
530
+ {
531
+ fn try_into_ref<'a>(&'a self) -> Result<&'a $type, Error>
532
+ {
533
+ match self
534
+ {
535
+ Value::$vn(v) => Ok(v),
536
+ _ => Err(
537
+ InternalError::InvalidValueCast {
538
+ value: self.clone(),
539
+ typename: stringify!($type),
540
+ }
541
+ .into(),
542
+ ),
543
+ }
544
+ }
545
+ }
546
+ };
547
+ }
548
+
549
+ impl_to_value!(bool, Boolean);
550
+ impl_to_value!(i64, Integer);
551
+ impl_to_value!(f64, Float);
552
+ impl_to_value!(String, String);
553
+ impl_to_value!(graph::Node, Node);
554
+ impl_to_value!(graph::Edge, Edge);
555
+ impl_to_value!(graph::Path, Path);
556
+ impl_to_value!(Vec<Value>, Array);
557
+ impl_to_value!(ValueMap, Map);
558
+
559
+ impl Into<Value> for &str
560
+ {
561
+ fn into(self) -> Value
562
+ {
563
+ Value::String(self.into())
564
+ }
565
+ }
566
+
567
+ /// Convenient macro for creating Array.
568
+ ///
569
+ /// Example:
570
+ ///
571
+ /// ```rust
572
+ /// # use gqlitedb::{ValueMap, map};
573
+ /// let value_map = array!("hello", 12);
574
+ /// ```
575
+ #[macro_export]
576
+ macro_rules! array {
577
+ () => (
578
+ $crate::Value::Array(Default::default())
579
+ );
580
+ ($($x:expr),+ $(,)?) => (
581
+ $crate::Value::Array(
582
+ vec![$($x.into()),+]
583
+ )
584
+ );
585
+ }
586
+
587
+ #[cfg(test)]
588
+ pub(crate) use array;
589
+
590
+ /// Convenient macro for creating ValueMap.
591
+ ///
592
+ /// Example:
593
+ ///
594
+ /// ```rust
595
+ /// # use gqlitedb::{ValueMap, map};
596
+ /// let value_map: ValueMap = map!("hello" => 12);
597
+ /// ```
598
+ #[macro_export]
599
+ macro_rules! map {
600
+ // map-like
601
+ ($($k:expr => $v:expr),* $(,)?) => {
602
+ {
603
+ core::convert::From::from([$(($k.to_string(), $v.into()),)*])
604
+ }
605
+ };
606
+ }
607
+
608
+ #[cfg(test)]
609
+ pub(crate) use map;