gqlite 1.5.1 → 1.7.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +10 -4
  3. data/ext/db-index/Cargo.toml +29 -0
  4. data/ext/db-index/src/hnsw/error.rs +66 -0
  5. data/ext/db-index/src/hnsw/graph_store.rs +272 -0
  6. data/ext/db-index/src/hnsw/id.rs +36 -0
  7. data/ext/db-index/src/hnsw/implementation.rs +1517 -0
  8. data/ext/db-index/src/hnsw/kernels.rs +1228 -0
  9. data/ext/db-index/src/hnsw/metric.rs +244 -0
  10. data/ext/db-index/src/hnsw/scalar.rs +72 -0
  11. data/ext/db-index/src/hnsw/simple_store.rs +140 -0
  12. data/ext/db-index/src/hnsw/store.rs +472 -0
  13. data/ext/db-index/src/hnsw/vector.rs +105 -0
  14. data/ext/db-index/src/hnsw/vectors.rs +568 -0
  15. data/ext/db-index/src/hnsw.rs +42 -0
  16. data/ext/db-index/src/lib.rs +3 -0
  17. data/ext/gqlitedb/Cargo.toml +19 -9
  18. data/ext/gqlitedb/benches/common/pokec.rs +62 -2
  19. data/ext/gqlitedb/benches/pokec_divan.rs +66 -2
  20. data/ext/gqlitedb/benches/pokec_iai.rs +60 -3
  21. data/ext/gqlitedb/release.toml +2 -2
  22. data/ext/gqlitedb/src/aggregators/arithmetic.rs +3 -1
  23. data/ext/gqlitedb/src/aggregators/containers.rs +1 -1
  24. data/ext/gqlitedb/src/aggregators/stats.rs +21 -12
  25. data/ext/gqlitedb/src/capi.rs +1 -1
  26. data/ext/gqlitedb/src/compiler/expression_analyser.rs +28 -20
  27. data/ext/gqlitedb/src/compiler/variables_manager.rs +97 -29
  28. data/ext/gqlitedb/src/compiler.rs +505 -225
  29. data/ext/gqlitedb/src/connection.rs +149 -11
  30. data/ext/gqlitedb/src/consts.rs +1 -2
  31. data/ext/gqlitedb/src/error.rs +123 -61
  32. data/ext/gqlitedb/src/functions/common.rs +39 -2
  33. data/ext/gqlitedb/src/functions/math.rs +8 -3
  34. data/ext/gqlitedb/src/functions/path.rs +48 -11
  35. data/ext/gqlitedb/src/functions/value.rs +1 -1
  36. data/ext/gqlitedb/src/functions.rs +23 -7
  37. data/ext/gqlitedb/src/graph.rs +1 -9
  38. data/ext/gqlitedb/src/interpreter/evaluators.rs +968 -130
  39. data/ext/gqlitedb/src/interpreter/instructions.rs +39 -2
  40. data/ext/gqlitedb/src/lib.rs +5 -4
  41. data/ext/gqlitedb/src/planner.rs +329 -0
  42. data/ext/gqlitedb/src/prelude.rs +3 -3
  43. data/ext/gqlitedb/src/store/pgrx.rs +1 -1
  44. data/ext/gqlitedb/src/store/postgres.rs +735 -7
  45. data/ext/gqlitedb/src/store/redb/hnsw_store.rs +702 -0
  46. data/ext/gqlitedb/src/store/redb/index.rs +274 -0
  47. data/ext/gqlitedb/src/store/redb.rs +1268 -113
  48. data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +28 -0
  49. data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +103 -0
  50. data/ext/gqlitedb/src/store/sqlbase.rs +146 -16
  51. data/ext/gqlitedb/src/store/sqlite.rs +569 -5
  52. data/ext/gqlitedb/src/store/vector_extract.rs +56 -0
  53. data/ext/gqlitedb/src/store.rs +123 -3
  54. data/ext/gqlitedb/src/tests/compiler.rs +207 -10
  55. data/ext/gqlitedb/src/tests/connection/postgres.rs +38 -3
  56. data/ext/gqlitedb/src/tests/connection/redb.rs +23 -0
  57. data/ext/gqlitedb/src/tests/connection/sqlite.rs +31 -0
  58. data/ext/gqlitedb/src/tests/connection.rs +61 -1
  59. data/ext/gqlitedb/src/tests/evaluators.rs +162 -7
  60. data/ext/gqlitedb/src/tests/parser.rs +54 -23
  61. data/ext/gqlitedb/src/tests/planner.rs +511 -0
  62. data/ext/gqlitedb/src/tests/store/postgres.rs +7 -0
  63. data/ext/gqlitedb/src/tests/store/redb.rs +8 -0
  64. data/ext/gqlitedb/src/tests/store/sqlite.rs +8 -0
  65. data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +182 -0
  66. data/ext/gqlitedb/src/tests/store/vector_index/redb.rs +386 -0
  67. data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +166 -0
  68. data/ext/gqlitedb/src/tests/store/vector_index.rs +2313 -0
  69. data/ext/gqlitedb/src/tests/store.rs +78 -14
  70. data/ext/gqlitedb/src/tests/templates/ast.rs +92 -16
  71. data/ext/gqlitedb/src/tests/templates/programs.rs +14 -7
  72. data/ext/gqlitedb/src/tests.rs +15 -9
  73. data/ext/gqlitedb/src/utils.rs +6 -1
  74. data/ext/gqlitedb/src/value/compare.rs +61 -3
  75. data/ext/gqlitedb/src/value.rs +136 -7
  76. data/ext/gqlitedb/templates/sql/postgres/metadata_delete.sql +1 -0
  77. data/ext/gqlitedb/templates/sql/postgres/node_select.sql +1 -1
  78. data/ext/gqlitedb/templates/sql/sqlite/metadata_delete.sql +1 -0
  79. data/ext/gqliterb/src/lib.rs +53 -8
  80. data/ext/gqlparser/Cargo.toml +25 -0
  81. data/ext/gqlparser/README.MD +9 -0
  82. data/ext/gqlparser/benches/pokec_divan.rs +34 -0
  83. data/ext/gqlparser/src/common.rs +69 -0
  84. data/ext/gqlparser/src/gqls/ast.rs +69 -0
  85. data/ext/gqlparser/src/gqls/constraint.rs +79 -0
  86. data/ext/gqlparser/src/gqls/error.rs +22 -0
  87. data/ext/gqlparser/src/gqls/parser.rs +813 -0
  88. data/ext/gqlparser/src/gqls/prelude.rs +8 -0
  89. data/ext/gqlparser/src/gqls/properties.rs +115 -0
  90. data/ext/gqlparser/src/gqls/resolve.rs +207 -0
  91. data/ext/gqlparser/src/gqls.rs +265 -0
  92. data/ext/gqlparser/src/lib.rs +7 -0
  93. data/ext/gqlparser/src/oc/ast.rs +680 -0
  94. data/ext/gqlparser/src/oc/error.rs +172 -0
  95. data/ext/gqlparser/src/oc/lexer.rs +429 -0
  96. data/ext/gqlparser/src/oc/parser/tests.rs +2284 -0
  97. data/ext/gqlparser/src/oc/parser.rs +2005 -0
  98. data/ext/gqlparser/src/oc.rs +33 -0
  99. data/ext/gqlparser/src/prelude.rs +3 -0
  100. data/ext/graphcore/Cargo.toml +1 -0
  101. data/ext/graphcore/src/error.rs +26 -0
  102. data/ext/graphcore/src/graph.rs +177 -51
  103. data/ext/graphcore/src/lib.rs +4 -2
  104. data/ext/graphcore/src/open_cypher.rs +12 -0
  105. data/ext/graphcore/src/table.rs +50 -2
  106. data/ext/graphcore/src/timestamp.rs +127 -104
  107. data/ext/graphcore/src/value/tensor.rs +739 -0
  108. data/ext/graphcore/src/value/value_map.rs +1 -1
  109. data/ext/graphcore/src/value.rs +343 -19
  110. metadata +90 -22
  111. data/ext/gqlitedb/src/parser/ast.rs +0 -604
  112. data/ext/gqlitedb/src/parser/parser_impl.rs +0 -1213
  113. data/ext/gqlitedb/src/parser.rs +0 -4
@@ -5,7 +5,7 @@ use std::{
5
5
  ops::{Deref, DerefMut},
6
6
  };
7
7
 
8
- use crate::{prelude::*, Value};
8
+ use crate::{Value, prelude::*};
9
9
 
10
10
  type ValueMapInner = std::collections::HashMap<String, Value>;
11
11
 
@@ -5,11 +5,13 @@ use std::{
5
5
  ops::{Add, Div, Mul, Neg, Rem, Sub},
6
6
  };
7
7
 
8
+ mod tensor;
8
9
  mod value_map;
9
10
 
10
- pub(crate) use crate::prelude::*;
11
11
  use crate::TimeStamp;
12
+ pub(crate) use crate::prelude::*;
12
13
 
14
+ pub use tensor::{DType, Tensor};
13
15
  pub use value_map::ValueMap;
14
16
 
15
17
  /// Represent a value in a properties for a Node or an Edge.
@@ -38,14 +40,18 @@ pub enum Value
38
40
  TimeStamp(timestamp::TimeStamp),
39
41
  /// Array of values.
40
42
  Array(Vec<Value>),
43
+ /// Dense tensor embedding (1D array of floats)
44
+ Tensor(Tensor),
41
45
  /// Unordered map of values.
42
46
  Map(ValueMap),
43
47
  /// A node in the graph.
44
48
  Node(graph::Node),
45
49
  /// An edge in the graph.
46
50
  Edge(graph::Edge),
51
+ /// A single path in the graph.
52
+ SinglePath(Box<graph::SinglePath>),
47
53
  /// A path in the graph.
48
- Path(graph::SinglePath),
54
+ Path(Box<graph::Path>),
49
55
  }
50
56
 
51
57
  impl Value
@@ -75,6 +81,42 @@ impl Value
75
81
  o => o,
76
82
  }
77
83
  }
84
+
85
+ /// Optimize a value that has been deserialized from a storage layer.
86
+ /// In particular, convert numeric arrays into native Tensor values.
87
+ pub fn optimize(self) -> Self
88
+ {
89
+ match self
90
+ {
91
+ Value::Array(arr) =>
92
+ {
93
+ let mut out = Vec::with_capacity(arr.len());
94
+ let mut all_numeric = true;
95
+ for v in arr.iter()
96
+ {
97
+ match v
98
+ {
99
+ Value::Float(f) => out.push(*f as f32),
100
+ Value::Integer(i) => out.push(*i as f32),
101
+ _ =>
102
+ {
103
+ all_numeric = false;
104
+ break;
105
+ }
106
+ }
107
+ }
108
+ if all_numeric
109
+ {
110
+ Value::Tensor(Tensor::from_f32_slice(&out))
111
+ }
112
+ else
113
+ {
114
+ Value::Array(arr.into_iter().map(|v| v.optimize()).collect())
115
+ }
116
+ }
117
+ other => other,
118
+ }
119
+ }
78
120
  }
79
121
  impl Hash for Value
80
122
  {
@@ -102,9 +144,25 @@ impl Hash for Value
102
144
  Value::String(s) => s.hash(state),
103
145
  Value::TimeStamp(ts) => ts.hash(state),
104
146
  Value::Array(a) => a.hash(state),
147
+ Value::Tensor(t) =>
148
+ {
149
+ for fl in t.iter()
150
+ {
151
+ let bits = if fl.is_nan()
152
+ {
153
+ 0x7fc00000u32
154
+ }
155
+ else
156
+ {
157
+ fl.to_bits()
158
+ };
159
+ bits.hash(state);
160
+ }
161
+ }
105
162
  Value::Map(m) => m.hash(state),
106
163
  Value::Node(n) => n.hash(state),
107
164
  Value::Edge(e) => e.hash(state),
165
+ Value::SinglePath(p) => p.hash(state),
108
166
  Value::Path(p) => p.hash(state),
109
167
  }
110
168
  }
@@ -123,8 +181,68 @@ impl Add for Value
123
181
  | Value::Edge(..)
124
182
  | Value::Map(..)
125
183
  | Value::TimeStamp(..)
184
+ | Value::SinglePath(..)
126
185
  | Value::Path(..) => Err(Error::InvalidBinaryOperands),
127
186
  Value::Null => Ok(Value::Null),
187
+ Self::Tensor(lhs) => match rhs
188
+ {
189
+ Self::Tensor(rhs_v) =>
190
+ {
191
+ if lhs.len() != rhs_v.len()
192
+ {
193
+ Err(Error::InvalidBinaryOperands)
194
+ }
195
+ else
196
+ {
197
+ let res = lhs
198
+ .iter()
199
+ .zip(rhs_v.iter())
200
+ .map(|(a, b)| a + b)
201
+ .collect::<Vec<f32>>();
202
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
203
+ }
204
+ }
205
+ Self::Float(rhs_f) =>
206
+ {
207
+ let scalar = rhs_f as f32;
208
+ let res = lhs.iter().map(|a| a + scalar).collect::<Vec<f32>>();
209
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
210
+ }
211
+ Self::Integer(rhs_i) =>
212
+ {
213
+ let scalar = rhs_i as f32;
214
+ let res = lhs.iter().map(|a| a + scalar).collect::<Vec<f32>>();
215
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
216
+ }
217
+ Self::Array(arr) =>
218
+ {
219
+ let mut rhs_vec = Vec::with_capacity(arr.len());
220
+ for v in arr.iter()
221
+ {
222
+ match v
223
+ {
224
+ Value::Float(f) => rhs_vec.push(*f as f32),
225
+ Value::Integer(i) => rhs_vec.push(*i as f32),
226
+ _ => return Err(Error::InvalidBinaryOperands),
227
+ }
228
+ }
229
+ if rhs_vec.len() != lhs.len()
230
+ {
231
+ Err(Error::InvalidBinaryOperands)
232
+ }
233
+ else
234
+ {
235
+ let res = lhs
236
+ .iter()
237
+ .zip(rhs_vec.iter())
238
+ .map(|(a, b)| a + b)
239
+ .collect::<Vec<f32>>();
240
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
241
+ }
242
+ }
243
+ Self::Null => Ok(Self::Null),
244
+ _ => Err(Error::InvalidBinaryOperands),
245
+ },
128
246
  Self::Array(lhs) => match rhs
129
247
  {
130
248
  Self::Array(rhs) =>
@@ -144,6 +262,12 @@ impl Add for Value
144
262
  {
145
263
  Self::Float(rhs) => Ok((lhs + rhs).into()),
146
264
  Self::Integer(rhs) => Ok((lhs + rhs as f64).into()),
265
+ Self::Tensor(rhs_v) =>
266
+ {
267
+ let scalar = lhs as f32;
268
+ let res = rhs_v.iter().map(|v| scalar + *v).collect::<Vec<f32>>();
269
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
270
+ }
147
271
  Self::Null => Ok(Self::Null),
148
272
  _ => Err(Error::InvalidBinaryOperands),
149
273
  },
@@ -151,6 +275,12 @@ impl Add for Value
151
275
  {
152
276
  Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
153
277
  Self::Integer(rhs) => Ok((lhs + rhs).into()),
278
+ Self::Tensor(rhs_v) =>
279
+ {
280
+ let scalar = lhs as f32;
281
+ let res = rhs_v.iter().map(|v| scalar + *v).collect::<Vec<f32>>();
282
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
283
+ }
154
284
  Self::Null => Ok(Self::Null),
155
285
  _ => Err(Error::InvalidBinaryOperands),
156
286
  },
@@ -181,19 +311,72 @@ macro_rules! impl_mdsr {
181
311
  | Value::Edge(..)
182
312
  | Value::Array(..)
183
313
  | Value::Map(..)
314
+ | Value::SinglePath(..)
184
315
  | Value::Path(..) => Err(Error::InvalidBinaryOperands.into()),
185
316
  Value::Null => Ok(Value::Null),
186
317
  Self::Float(lhs) => match rhs
187
318
  {
188
319
  Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
189
320
  Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
321
+ Self::Tensor(rhs_v) =>
322
+ {
323
+ let scalar = lhs as f32;
324
+ let res = rhs_v.iter().map(|v| scalar.$op(*v)).collect::<Vec<f32>>();
325
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
326
+ }
190
327
  Self::Null => Ok(Self::Null),
191
328
  _ => Err(Error::InvalidBinaryOperands.into()),
192
329
  },
330
+
193
331
  Self::Integer(lhs) => match rhs
194
332
  {
195
333
  Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
196
334
  Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
335
+ Self::Tensor(rhs_v) =>
336
+ {
337
+ let scalar = lhs as f32;
338
+ let res = rhs_v.iter().map(|v| scalar.$op(*v)).collect::<Vec<f32>>();
339
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
340
+ }
341
+ Self::Null => Ok(Self::Null),
342
+ _ => Err(Error::InvalidBinaryOperands.into()),
343
+ },
344
+ Self::Tensor(lhs_v) => match rhs
345
+ {
346
+ Self::Tensor(rhs_v) =>
347
+ {
348
+ if lhs_v.len() != rhs_v.len()
349
+ {
350
+ Err(Error::InvalidBinaryOperands.into())
351
+ }
352
+ else
353
+ {
354
+ let res = lhs_v
355
+ .iter()
356
+ .zip(rhs_v.iter())
357
+ .map(|(a, b)| (*a).$op(*b))
358
+ .collect::<Vec<f32>>();
359
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
360
+ }
361
+ }
362
+ Self::Float(rhs) =>
363
+ {
364
+ let rhs_scalar = rhs as f32;
365
+ let res = lhs_v
366
+ .iter()
367
+ .map(|a| (*a).$op(rhs_scalar))
368
+ .collect::<Vec<f32>>();
369
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
370
+ }
371
+ Self::Integer(rhs) =>
372
+ {
373
+ let rhs_scalar = rhs as f32;
374
+ let res = lhs_v
375
+ .iter()
376
+ .map(|a| (*a).$op(rhs_scalar))
377
+ .collect::<Vec<f32>>();
378
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
379
+ }
197
380
  Self::Null => Ok(Self::Null),
198
381
  _ => Err(Error::InvalidBinaryOperands.into()),
199
382
  },
@@ -223,6 +406,7 @@ impl Value
223
406
  | Value::Edge(..)
224
407
  | Value::Array(..)
225
408
  | Value::Map(..)
409
+ | Value::SinglePath(..)
226
410
  | Value::Path(..) => Err(Error::InvalidBinaryOperands),
227
411
  Value::Null => Ok(Value::Null),
228
412
  Self::Float(lhs) => match rhs
@@ -243,6 +427,43 @@ impl Value
243
427
  Self::Null => Ok(Self::Null),
244
428
  _ => Err(Error::InvalidBinaryOperands),
245
429
  },
430
+ Self::Tensor(lhs_v) => match rhs
431
+ {
432
+ Self::Float(rhs) =>
433
+ {
434
+ let res = lhs_v
435
+ .iter()
436
+ .map(|a| a.powf(rhs as f32))
437
+ .collect::<Vec<f32>>();
438
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
439
+ }
440
+ Self::Integer(rhs) =>
441
+ {
442
+ let res = lhs_v
443
+ .iter()
444
+ .map(|a| a.powf(rhs as f32))
445
+ .collect::<Vec<f32>>();
446
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
447
+ }
448
+ Self::Tensor(rhs_v) =>
449
+ {
450
+ if lhs_v.len() != rhs_v.len()
451
+ {
452
+ Err(Error::InvalidBinaryOperands)
453
+ }
454
+ else
455
+ {
456
+ let res = lhs_v
457
+ .iter()
458
+ .zip(rhs_v.iter())
459
+ .map(|(a, b)| a.powf(*b))
460
+ .collect::<Vec<f32>>();
461
+ Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
462
+ }
463
+ }
464
+ Self::Null => Ok(Self::Null),
465
+ _ => Err(Error::InvalidBinaryOperands),
466
+ },
246
467
  }
247
468
  }
248
469
  }
@@ -256,6 +477,7 @@ impl Neg for Value
256
477
  {
257
478
  Self::Float(fl) => Ok((-fl).into()),
258
479
  Self::Integer(i) => Ok((-i).into()),
480
+ Self::Tensor(t) => Ok(Value::Tensor(t.into_iter().map(|x| -x).collect())),
259
481
  Value::Null => Ok(Value::Null),
260
482
  Value::Boolean(..)
261
483
  | Value::Key(..)
@@ -265,6 +487,7 @@ impl Neg for Value
265
487
  | Value::TimeStamp(..)
266
488
  | Value::Array(..)
267
489
  | Value::Map(..)
490
+ | Value::SinglePath(..)
268
491
  | Value::Path(..) => Err(Error::InvalidNegationOperands),
269
492
  }
270
493
  }
@@ -284,9 +507,11 @@ impl std::fmt::Display for Value
284
507
  Value::String(s) => write!(f, "{}", s),
285
508
  Value::TimeStamp(t) => write!(f, "{}", t),
286
509
  Value::Array(v) => write!(f, "[{}]", v.iter().map(|x| x.to_string()).join(", ")),
510
+ Value::Tensor(v) => write!(f, "[{}]", v.iter().map(|x| x.to_string()).join(", ")),
287
511
  Value::Map(o) => write!(f, "{}", o),
288
512
  Value::Node(n) => write!(f, "{}", n),
289
513
  Value::Edge(e) => write!(f, "{}", e),
514
+ Value::SinglePath(p) => write!(f, "{}", p),
290
515
  Value::Path(p) => write!(f, "{}", p),
291
516
  }
292
517
  }
@@ -331,9 +556,26 @@ pub enum FromValueResult<T>
331
556
  Invalid(Value),
332
557
  }
333
558
 
559
+ fn identity<T>(t: T) -> T
560
+ {
561
+ t
562
+ }
563
+ fn boxed<T>(t: T) -> Box<T>
564
+ {
565
+ Box::new(t)
566
+ }
567
+
568
+ // Suppression is needed because this function must take a
569
+ // box as argument to be used in the macro bellow
570
+ #[allow(clippy::boxed_local)]
571
+ fn unboxed<T>(t: Box<T>) -> T
572
+ {
573
+ *t
574
+ }
575
+
334
576
  macro_rules! impl_from_value {
335
- ($type:ty, $vn:tt, try) => {
336
- impl_from_value!($type, $vn);
577
+ ($type:ty, $vn:tt, $factory: ident, $defactory: ident, try) => {
578
+ impl_from_value!($type, $vn, $factory, $defactory);
337
579
  impl TryFrom<Value> for $type
338
580
  {
339
581
  type Error = Error;
@@ -341,7 +583,7 @@ macro_rules! impl_from_value {
341
583
  {
342
584
  match value
343
585
  {
344
- Value::$vn(v) => Ok(v),
586
+ Value::$vn(v) => Ok($defactory(v)),
345
587
  _ => Err(
346
588
  Error::InvalidValueCast {
347
589
  value: Box::new(value),
@@ -358,18 +600,18 @@ macro_rules! impl_from_value {
358
600
  {
359
601
  match value
360
602
  {
361
- Value::$vn(v) => FromValueResult::Ok(v),
603
+ Value::$vn(v) => FromValueResult::Ok($defactory(v)),
362
604
  _ => FromValueResult::Invalid(value),
363
605
  }
364
606
  }
365
607
  }
366
608
  };
367
- ($type:ty, $vn:tt) => {
609
+ ($type:ty, $vn:tt, $factory: ident, $defactory: ident) => {
368
610
  impl From<$type> for Value
369
611
  {
370
612
  fn from(v: $type) -> Value
371
613
  {
372
- Value::$vn(v)
614
+ Value::$vn($factory(v))
373
615
  }
374
616
  }
375
617
 
@@ -432,17 +674,99 @@ macro_rules! impl_from_value {
432
674
  };
433
675
  }
434
676
 
435
- impl_from_value!(graph::Key, Key, try);
436
- impl_from_value!(bool, Boolean, try);
437
- impl_from_value!(i64, Integer, try);
438
- impl_from_value!(f64, Float);
439
- impl_from_value!(String, String, try);
440
- impl_from_value!(TimeStamp, TimeStamp);
441
- impl_from_value!(graph::Node, Node, try);
442
- impl_from_value!(graph::Edge, Edge, try);
443
- impl_from_value!(graph::SinglePath, Path, try);
444
- impl_from_value!(Vec<Value>, Array, try);
445
- impl_from_value!(ValueMap, Map, try);
677
+ impl_from_value!(graph::Key, Key, identity, identity, try);
678
+ impl_from_value!(bool, Boolean, identity, identity, try);
679
+ impl_from_value!(i64, Integer, identity, identity, try);
680
+ impl_from_value!(f64, Float, identity, identity);
681
+ impl_from_value!(String, String, identity, identity, try);
682
+ impl_from_value!(TimeStamp, TimeStamp, identity, identity);
683
+ impl_from_value!(graph::Node, Node, identity, identity, try);
684
+ impl_from_value!(graph::Edge, Edge, identity, identity, try);
685
+ impl_from_value!(graph::SinglePath, SinglePath, boxed, unboxed, try);
686
+ impl_from_value!(graph::Path, Path, boxed, unboxed, try);
687
+ impl_from_value!(Vec<Value>, Array, identity, identity, try);
688
+ impl_from_value!(ValueMap, Map, identity, identity, try);
689
+ impl_from_value!(Tensor, Tensor, identity, identity);
690
+
691
+ impl TryFrom<Value> for Tensor
692
+ {
693
+ type Error = Error;
694
+ fn try_from(value: Value) -> Result<Tensor, Self::Error>
695
+ {
696
+ match value
697
+ {
698
+ Value::Tensor(v) => Ok(v),
699
+ Value::Array(arr) =>
700
+ {
701
+ let mut out = Vec::with_capacity(arr.len());
702
+ for v in arr.iter()
703
+ {
704
+ match v
705
+ {
706
+ Value::Float(f) => out.push(*f as f32),
707
+ Value::Integer(i) => out.push(*i as f32),
708
+ _ =>
709
+ {
710
+ return Err(Error::InvalidValueCast {
711
+ value: Box::new(Value::Array(arr.clone())),
712
+ typename: "Vec<f32>",
713
+ });
714
+ }
715
+ }
716
+ }
717
+ Ok(Tensor::from_f32_slice(&out))
718
+ }
719
+ _ => Err(Error::InvalidValueCast {
720
+ value: Box::new(value),
721
+ typename: "Vec<f32>",
722
+ }),
723
+ }
724
+ }
725
+ }
726
+
727
+ impl TryFrom<Value> for Vec<f32>
728
+ {
729
+ type Error = Error;
730
+ fn try_from(value: Value) -> Result<Vec<f32>, Self::Error>
731
+ {
732
+ match value
733
+ {
734
+ Value::Tensor(t) => Ok(t.to_f32_vec()),
735
+ Value::Array(arr) =>
736
+ {
737
+ let mut out = Vec::with_capacity(arr.len());
738
+ for v in arr.iter()
739
+ {
740
+ match v
741
+ {
742
+ Value::Float(f) => out.push(*f as f32),
743
+ Value::Integer(i) => out.push(*i as f32),
744
+ _ =>
745
+ {
746
+ return Err(Error::InvalidValueCast {
747
+ value: Box::new(Value::Array(arr.clone())),
748
+ typename: "Vec<f32>",
749
+ });
750
+ }
751
+ }
752
+ }
753
+ Ok(out)
754
+ }
755
+ _ => Err(Error::InvalidValueCast {
756
+ value: Box::new(value),
757
+ typename: "Vec<f32>",
758
+ }),
759
+ }
760
+ }
761
+ }
762
+
763
+ impl From<Vec<f32>> for Value
764
+ {
765
+ fn from(v: Vec<f32>) -> Value
766
+ {
767
+ Value::Tensor(Tensor::from(v))
768
+ }
769
+ }
446
770
 
447
771
  impl TryFrom<Value> for f64
448
772
  {