gqlite 1.2.3 → 1.3.0

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +20 -0
  3. data/ext/gqlitedb/Cargo.toml +77 -0
  4. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
  5. data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
  6. data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
  7. data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
  8. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +10 -9
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +6 -4
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +27 -31
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +37 -41
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/connection.rs +42 -84
  16. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +105 -34
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +2 -2
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +2 -2
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +1 -1
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/path.rs +15 -20
  22. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +2 -2
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +6 -6
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +20 -20
  25. data/ext/gqlitedb/src/graph.rs +11 -0
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +160 -194
  27. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +2 -1
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -4
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +44 -52
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +1 -1
  31. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +50 -28
  32. data/ext/gqlitedb/src/parser.rs +4 -0
  33. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  34. data/ext/gqlitedb/src/query_result.rs +88 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +226 -148
  36. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +111 -128
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +22 -22
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +32 -76
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +95 -111
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  44. data/ext/gqlitedb/src/value.rs +225 -0
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +15 -5
  46. data/ext/gqliterb/Cargo.toml +12 -35
  47. data/ext/gqliterb/src/lib.rs +60 -38
  48. data/ext/graphcore/Cargo.toml +19 -0
  49. data/ext/graphcore/README.MD +4 -0
  50. data/ext/graphcore/release.toml +1 -0
  51. data/ext/graphcore/src/error.rs +28 -0
  52. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +134 -38
  53. data/ext/graphcore/src/lib.rs +16 -0
  54. data/ext/graphcore/src/prelude.rs +4 -0
  55. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  56. data/ext/graphcore/src/table.rs +272 -0
  57. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  58. data/ext/graphcore/src/value.rs +413 -0
  59. metadata +94 -83
  60. data/ext/gqliterb/.cargo/config.toml +0 -2
  61. data/ext/gqliterb/Cargo.lock +0 -1116
  62. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2115
  63. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -138
  64. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  65. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -609
  66. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  67. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  68. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  69. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  70. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +0 -0
  71. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -28,11 +28,12 @@ impl ValueMap
28
28
  .map(|(k, v)| (k, v.remove_null()))
29
29
  .collect()
30
30
  }
31
- pub(crate) fn remove_value<'a>(
31
+ /// Remove a value in the given path.
32
+ pub fn remove_value<'a>(
32
33
  &mut self,
33
34
  field: Option<&'a String>,
34
35
  mut path: impl Iterator<Item = &'a String>,
35
- ) -> crate::Result<()>
36
+ ) -> Result<()>
36
37
  {
37
38
  if let Some(field) = field
38
39
  {
@@ -47,9 +48,9 @@ impl ValueMap
47
48
  }
48
49
  None =>
49
50
  {}
50
- _ => Err(InternalError::Unimplemented(
51
- "remove_value should get a better error",
52
- ))?, // TODO
51
+ _ => Err(Error::MissingKeyInPath {
52
+ key: field.to_owned(),
53
+ })?,
53
54
  }
54
55
  }
55
56
  else
@@ -59,18 +60,17 @@ impl ValueMap
59
60
  }
60
61
  else
61
62
  {
62
- Err(InternalError::Unimplemented(
63
- "remove_value should get a better error",
64
- ))? // TODO
63
+ Err(Error::MissingKey)?
65
64
  }
66
65
  Ok(())
67
66
  }
68
- pub(crate) fn add_values<'a>(
67
+ /// Add a value at the given path.
68
+ pub fn add_values<'a>(
69
69
  &mut self,
70
70
  field: Option<&'a String>,
71
71
  mut path: impl Iterator<Item = &'a String>,
72
72
  value: ValueMap,
73
- ) -> crate::Result<()>
73
+ ) -> Result<()>
74
74
  {
75
75
  if let Some(field) = field
76
76
  {
@@ -90,38 +90,35 @@ impl ValueMap
90
90
  o.set_value(Some(next_field), path, value.remove_null().into())?;
91
91
  self.insert(field.to_owned(), o.into());
92
92
  }
93
- _ => Err(InternalError::Unimplemented(
94
- "add_values should get a better error",
95
- ))?, // TODO
93
+ _ => Err(Error::MissingKeyInPath {
94
+ key: field.to_owned(),
95
+ })?,
96
96
  }
97
97
  }
98
98
  else
99
99
  {
100
100
  match v
101
101
  {
102
- Some(v) =>
102
+ Some(v) => match v
103
103
  {
104
- match v
104
+ Value::Map(object) =>
105
105
  {
106
- Value::Map(object) =>
106
+ for (k, v) in value.into_iter()
107
107
  {
108
- for (k, v) in value.into_iter()
108
+ if v.is_null()
109
+ {
110
+ object.remove(&k);
111
+ }
112
+ else
109
113
  {
110
- if v.is_null()
111
- {
112
- object.remove(&k);
113
- }
114
- else
115
- {
116
- object.insert(k, v);
117
- }
114
+ object.insert(k, v);
118
115
  }
119
116
  }
120
- _ => Err(InternalError::Unimplemented(
121
- "add_values should get a better error",
122
- ))?, // TODO
123
117
  }
124
- }
118
+ _ => Err(Error::MissingKeyInPath {
119
+ key: field.to_owned(),
120
+ })?,
121
+ },
125
122
  None =>
126
123
  {
127
124
  self.insert(field.to_owned(), value.remove_null().into());
@@ -145,12 +142,13 @@ impl ValueMap
145
142
  }
146
143
  Ok(())
147
144
  }
148
- pub(crate) fn set_value<'a>(
145
+ /// Set the value in the given path. Unlike add_value, it will complain if there is no existing value.
146
+ pub fn set_value<'a>(
149
147
  &mut self,
150
148
  field: Option<&'a String>,
151
149
  mut path: impl Iterator<Item = &'a String>,
152
150
  value: Value,
153
- ) -> crate::Result<()>
151
+ ) -> Result<()>
154
152
  {
155
153
  if let Some(field) = field
156
154
  {
@@ -173,29 +171,26 @@ impl ValueMap
173
171
  self.insert(field.to_owned(), o.into());
174
172
  }
175
173
  }
176
- _ => Err(InternalError::Unimplemented(
177
- "update_value should get a better error",
178
- ))?, // TODO
174
+ _ => Err(Error::MissingKeyInPath {
175
+ key: field.to_owned(),
176
+ })?,
179
177
  }
180
178
  }
179
+ else if value.is_null()
180
+ {
181
+ self.remove(field);
182
+ }
181
183
  else
182
184
  {
183
- if value.is_null()
184
- {
185
- self.remove(field);
186
- }
187
- else
185
+ match v
188
186
  {
189
- match v
187
+ Some(v) =>
190
188
  {
191
- Some(v) =>
192
- {
193
- *v = value;
194
- }
195
- None =>
196
- {
197
- self.insert(field.to_owned(), value);
198
- }
189
+ *v = value;
190
+ }
191
+ None =>
192
+ {
193
+ self.insert(field.to_owned(), value);
199
194
  }
200
195
  }
201
196
  }
@@ -211,7 +206,7 @@ impl ValueMap
211
206
  *self = o;
212
207
  Ok(())
213
208
  }
214
- _ => Err(InternalError::Unimplemented("set_value should get a better error").into()), // TODO
209
+ _ => Err(Error::MissingKey),
215
210
  }
216
211
  }
217
212
  }
@@ -0,0 +1,413 @@
1
+ use itertools::Itertools as _;
2
+ use serde::{Deserialize, Serialize};
3
+ use std::{
4
+ hash::Hash,
5
+ ops::{Add, Div, Mul, Neg, Rem, Sub},
6
+ };
7
+
8
+ mod value_map;
9
+
10
+ pub(crate) use crate::prelude::*;
11
+
12
+ pub use value_map::ValueMap;
13
+
14
+ /// Represent a value in a properties for a Node or an Edge.
15
+ #[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
16
+ #[serde(untagged)]
17
+ pub enum Value
18
+ {
19
+ /// Null value.
20
+ #[default]
21
+ Null,
22
+ /// A UUID Key in the graph.
23
+ Key(graph::Key),
24
+ /// Boolean value.
25
+ Boolean(bool),
26
+ /// Signed integer value.
27
+ Integer(i64),
28
+ #[serde(
29
+ serialize_with = "serialize_with::serialize_float",
30
+ deserialize_with = "serialize_with::deserialize_float"
31
+ )]
32
+ /// Floating point value.
33
+ Float(f64),
34
+ /// String value.
35
+ String(String),
36
+ /// Array of values.
37
+ Array(Vec<Value>),
38
+ /// Unordered map of values.
39
+ Map(ValueMap),
40
+ /// A node in the graph.
41
+ Node(graph::Node),
42
+ /// An edge in the graph.
43
+ Edge(graph::Edge),
44
+ /// A path in the graph.
45
+ Path(graph::SinglePath),
46
+ }
47
+
48
+ impl Value
49
+ {
50
+ /// Transform this value into a map. This function is guaranteed to succeed,
51
+ /// in case the value does not contains a map, it will create a default empty
52
+ /// map.
53
+ pub fn into_map(self) -> ValueMap
54
+ {
55
+ match self
56
+ {
57
+ Value::Map(o) => o.clone(),
58
+ _ => ValueMap::new(),
59
+ }
60
+ }
61
+ /// Return true if the value is null, false otherwise.
62
+ pub fn is_null(&self) -> bool
63
+ {
64
+ matches!(self, Value::Null)
65
+ }
66
+ /// Remove all elements of a map that are null. Walk through the map values recursively.
67
+ pub fn remove_null(self) -> Self
68
+ {
69
+ match self
70
+ {
71
+ Value::Map(object) => object.remove_null().into(),
72
+ o => o,
73
+ }
74
+ }
75
+ }
76
+ impl Hash for Value
77
+ {
78
+ fn hash<H: std::hash::Hasher>(&self, state: &mut H)
79
+ {
80
+ match self
81
+ {
82
+ Value::Null =>
83
+ {}
84
+ Value::Key(k) => k.hash(state),
85
+ Value::Boolean(b) => b.hash(state),
86
+ Value::Integer(i) => i.hash(state),
87
+ Value::Float(f) =>
88
+ {
89
+ let bits = if f.is_nan()
90
+ {
91
+ 0x7ff8000000000000
92
+ }
93
+ else
94
+ {
95
+ f.to_bits()
96
+ };
97
+ bits.hash(state);
98
+ }
99
+ Value::String(s) => s.hash(state),
100
+ Value::Array(a) => a.hash(state),
101
+ Value::Map(m) => m.hash(state),
102
+ Value::Node(n) => n.hash(state),
103
+ Value::Edge(e) => e.hash(state),
104
+ Value::Path(p) => p.hash(state),
105
+ }
106
+ }
107
+ }
108
+
109
+ impl Add for Value
110
+ {
111
+ type Output = Result<Value>;
112
+ fn add(self, rhs: Self) -> Self::Output
113
+ {
114
+ match self
115
+ {
116
+ Value::Boolean(..)
117
+ | Value::Key(..)
118
+ | Value::Node(..)
119
+ | Value::Edge(..)
120
+ | Value::Map(..)
121
+ | Value::Path(..) => Err(Error::InvalidBinaryOperands),
122
+ Value::Null => Ok(Value::Null),
123
+ Self::Array(lhs) => match rhs
124
+ {
125
+ Self::Array(rhs) =>
126
+ {
127
+ let mut lhs = lhs.clone();
128
+ lhs.append(&mut rhs.clone());
129
+ Ok(lhs.into())
130
+ }
131
+ _ =>
132
+ {
133
+ let mut lhs = lhs.clone();
134
+ lhs.push(rhs.clone());
135
+ Ok(lhs.into())
136
+ }
137
+ },
138
+ Self::Float(lhs) => match rhs
139
+ {
140
+ Self::Float(rhs) => Ok((lhs + rhs).into()),
141
+ Self::Integer(rhs) => Ok((lhs + rhs as f64).into()),
142
+ Self::Null => Ok(Self::Null),
143
+ _ => Err(Error::InvalidBinaryOperands),
144
+ },
145
+ Self::Integer(lhs) => match rhs
146
+ {
147
+ Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
148
+ Self::Integer(rhs) => Ok((lhs + rhs).into()),
149
+ Self::Null => Ok(Self::Null),
150
+ _ => Err(Error::InvalidBinaryOperands),
151
+ },
152
+ Self::String(lhs) => match rhs
153
+ {
154
+ Self::String(rhs) => Ok((lhs + &rhs).into()),
155
+ Self::Null => Ok(Self::Null),
156
+ _ => Err(Error::InvalidBinaryOperands),
157
+ },
158
+ }
159
+ }
160
+ }
161
+
162
+ macro_rules! impl_mdsr {
163
+ ($x:tt, $op:tt) => {
164
+ impl $x for Value
165
+ {
166
+ type Output = Result<Value>;
167
+ fn $op(self, rhs: Self) -> Self::Output
168
+ {
169
+ match self
170
+ {
171
+ Value::Boolean(..)
172
+ | Value::Key(..)
173
+ | Value::String(..)
174
+ | Value::Node(..)
175
+ | Value::Edge(..)
176
+ | Value::Array(..)
177
+ | Value::Map(..)
178
+ | Value::Path(..) => Err(Error::InvalidBinaryOperands.into()),
179
+ Value::Null => Ok(Value::Null),
180
+ Self::Float(lhs) => match rhs
181
+ {
182
+ Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
183
+ Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
184
+ Self::Null => Ok(Self::Null),
185
+ _ => Err(Error::InvalidBinaryOperands.into()),
186
+ },
187
+ Self::Integer(lhs) => match rhs
188
+ {
189
+ Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
190
+ Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
191
+ Self::Null => Ok(Self::Null),
192
+ _ => Err(Error::InvalidBinaryOperands.into()),
193
+ },
194
+ }
195
+ }
196
+ }
197
+ };
198
+ }
199
+
200
+ impl_mdsr!(Mul, mul);
201
+ impl_mdsr!(Sub, sub);
202
+ impl_mdsr!(Div, div);
203
+ impl_mdsr!(Rem, rem);
204
+
205
+ impl Value
206
+ {
207
+ /// Compute this value to the power of rhs. Return an error if called a non-number values.
208
+ pub fn pow(self, rhs: Value) -> Result<Value>
209
+ {
210
+ match self
211
+ {
212
+ Value::Boolean(..)
213
+ | Value::Key(..)
214
+ | Value::String(..)
215
+ | Value::Node(..)
216
+ | Value::Edge(..)
217
+ | Value::Array(..)
218
+ | Value::Map(..)
219
+ | Value::Path(..) => Err(Error::InvalidBinaryOperands),
220
+ Value::Null => Ok(Value::Null),
221
+ Self::Float(lhs) => match rhs
222
+ {
223
+ Self::Float(rhs) => Ok(lhs.powf(rhs).into()),
224
+ Self::Integer(rhs) => Ok(lhs.powf(rhs as f64).into()),
225
+ Self::Null => Ok(Self::Null),
226
+ _ => Err(Error::InvalidBinaryOperands),
227
+ },
228
+ Self::Integer(lhs) => match rhs
229
+ {
230
+ Self::Float(rhs) => Ok((lhs as f64).powf(rhs).into()),
231
+ Self::Integer(rhs) => match rhs.try_into()
232
+ {
233
+ Ok(rhs) => Ok(lhs.pow(rhs).into()),
234
+ Err(_) => Ok((lhs as f64).powf(rhs as f64).into()),
235
+ },
236
+ Self::Null => Ok(Self::Null),
237
+ _ => Err(Error::InvalidBinaryOperands),
238
+ },
239
+ }
240
+ }
241
+ }
242
+
243
+ impl Neg for Value
244
+ {
245
+ type Output = Result<Value>;
246
+ fn neg(self) -> Self::Output
247
+ {
248
+ match self
249
+ {
250
+ Self::Float(fl) => Ok((-fl).into()),
251
+ Self::Integer(i) => Ok((-i).into()),
252
+ Value::Null => Ok(Value::Null),
253
+ Value::Boolean(..)
254
+ | Value::Key(..)
255
+ | Value::String(..)
256
+ | Value::Node(..)
257
+ | Value::Edge(..)
258
+ | Value::Array(..)
259
+ | Value::Map(..)
260
+ | Value::Path(..) => Err(Error::InvalidNegationOperands),
261
+ }
262
+ }
263
+ }
264
+
265
+ impl std::fmt::Display for Value
266
+ {
267
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
268
+ {
269
+ match self
270
+ {
271
+ Value::Null => write!(f, "null"),
272
+ Value::Key(k) => write!(f, "<{}>", k.uuid()),
273
+ Value::Boolean(b) => write!(f, "{}", b),
274
+ Value::Integer(i) => write!(f, "{}", i),
275
+ Value::Float(fl) => write!(f, "{}", fl),
276
+ Value::String(s) => write!(f, "{}", s),
277
+ Value::Array(v) => write!(f, "[{}]", v.iter().map(|x| x.to_string()).join(", ")),
278
+ Value::Map(o) => write!(f, "{}", o),
279
+ Value::Node(n) => write!(f, "{}", n),
280
+ Value::Edge(e) => write!(f, "{}", e),
281
+ Value::Path(p) => write!(f, "{}", p),
282
+ }
283
+ }
284
+ }
285
+
286
+ /// Trait to return a reference to the underlying type
287
+ pub trait ValueTryIntoRef<T>
288
+ {
289
+ /// Return a reference to T
290
+ fn try_into_ref(&self) -> Result<&T, Error>;
291
+ }
292
+
293
+ impl ValueTryIntoRef<Value> for Value
294
+ {
295
+ fn try_into_ref(&self) -> Result<&Value, Error>
296
+ {
297
+ Ok(self)
298
+ }
299
+ }
300
+
301
+ macro_rules! impl_to_value {
302
+ ($type:ty, $vn:tt) => {
303
+ impl From<$type> for Value
304
+ {
305
+ fn from(v: $type) -> Value
306
+ {
307
+ Value::$vn(v)
308
+ }
309
+ }
310
+
311
+ impl From<Vec<$type>> for Value
312
+ {
313
+ fn from(v: Vec<$type>) -> Value
314
+ {
315
+ Value::Array(v.into_iter().map(|v| v.into()).collect())
316
+ }
317
+ }
318
+ impl TryInto<$type> for Value
319
+ {
320
+ type Error = Error;
321
+ fn try_into(self) -> Result<$type, Self::Error>
322
+ {
323
+ match self
324
+ {
325
+ Value::$vn(v) => Ok(v),
326
+ _ => Err(
327
+ Error::InvalidValueCast {
328
+ value: Box::new(self),
329
+ typename: stringify!($type),
330
+ }
331
+ .into(),
332
+ ),
333
+ }
334
+ }
335
+ }
336
+
337
+ impl ValueTryIntoRef<$type> for Value
338
+ {
339
+ fn try_into_ref(&self) -> Result<&$type, Error>
340
+ {
341
+ match self
342
+ {
343
+ Value::$vn(v) => Ok(v),
344
+ _ => Err(
345
+ Error::InvalidValueCast {
346
+ value: Box::new(self.clone()),
347
+ typename: stringify!($type),
348
+ }
349
+ .into(),
350
+ ),
351
+ }
352
+ }
353
+ }
354
+ };
355
+ }
356
+
357
+ impl_to_value!(graph::Key, Key);
358
+ impl_to_value!(bool, Boolean);
359
+ impl_to_value!(i64, Integer);
360
+ impl_to_value!(f64, Float);
361
+ impl_to_value!(String, String);
362
+ impl_to_value!(graph::Node, Node);
363
+ impl_to_value!(graph::Edge, Edge);
364
+ impl_to_value!(graph::SinglePath, Path);
365
+ impl_to_value!(Vec<Value>, Array);
366
+ impl_to_value!(ValueMap, Map);
367
+
368
+ impl From<&str> for Value
369
+ {
370
+ fn from(val: &str) -> Self
371
+ {
372
+ Value::String(val.into())
373
+ }
374
+ }
375
+
376
+ /// Convenient macro for creating Array.
377
+ ///
378
+ /// Example:
379
+ ///
380
+ /// ```rust
381
+ /// # use graphcore::{Value, array};
382
+ /// let value_arr: Value = array!("hello", 12);
383
+ /// ```
384
+ #[macro_export]
385
+ macro_rules! array {
386
+ () => (
387
+ $crate::Value::Array(Default::default())
388
+ );
389
+ ($($x:expr),+ $(,)?) => (
390
+ $crate::Value::Array(
391
+ vec![$($x.into()),+]
392
+ )
393
+ );
394
+ }
395
+
396
+ /// Convenient macro for creating ValueMap.
397
+ ///
398
+ /// Example:
399
+ ///
400
+ /// ```rust
401
+ /// # use graphcore::{ValueMap, value_map};
402
+ /// let value_map: ValueMap = value_map!("hello" => 12);
403
+ /// ```
404
+ #[macro_export]
405
+ macro_rules! value_map {
406
+ // map-like
407
+ ($($k:expr => $v:expr),* $(,)?) => {
408
+ {
409
+ let value_map: $crate::ValueMap = core::convert::From::from([$(($k.to_string(), $v.into()),)*]);
410
+ value_map
411
+ }
412
+ };
413
+ }