gqlite 1.2.2 → 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 (104) 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}/release.toml +2 -2
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +34 -10
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
  16. data/ext/gqlitedb/src/connection.rs +300 -0
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
  22. data/ext/gqlitedb/src/functions/path.rs +75 -0
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
  25. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
  27. data/ext/gqlitedb/src/graph.rs +11 -0
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
  31. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
  32. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
  33. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
  34. data/ext/gqlitedb/src/parser.rs +4 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  36. data/ext/gqlitedb/src/query_result.rs +88 -0
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +260 -170
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
  44. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  46. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  47. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  48. data/ext/gqlitedb/src/value.rs +225 -0
  49. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +22 -18
  50. data/ext/gqliterb/Cargo.toml +12 -34
  51. data/ext/gqliterb/src/lib.rs +67 -39
  52. data/ext/graphcore/Cargo.toml +19 -0
  53. data/ext/graphcore/README.MD +4 -0
  54. data/ext/graphcore/release.toml +1 -0
  55. data/ext/graphcore/src/error.rs +28 -0
  56. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +146 -35
  57. data/ext/graphcore/src/lib.rs +16 -0
  58. data/ext/graphcore/src/prelude.rs +4 -0
  59. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  60. data/ext/graphcore/src/table.rs +272 -0
  61. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  62. data/ext/graphcore/src/value.rs +413 -0
  63. metadata +94 -83
  64. data/ext/gqliterb/.cargo/config.toml +0 -2
  65. data/ext/gqliterb/Cargo.lock +0 -1109
  66. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
  67. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
  68. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
  69. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
  70. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  71. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  103. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  104. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -0,0 +1,272 @@
1
+ use crate::{prelude::*, Value, ValueTryIntoRef};
2
+
3
+ /// Table of values
4
+ #[derive(Debug, Default, Clone, PartialEq)]
5
+ pub struct Table
6
+ {
7
+ headers: Vec<String>,
8
+ data: Vec<crate::Value>,
9
+ }
10
+
11
+ impl Table
12
+ {
13
+ /// Create a new table, with the given headers and data.
14
+ /// It is assumed that number of column is equalt to headers, and the number
15
+ /// of row is equal to length of data divided by number of columns.
16
+ pub fn new(headers: Vec<String>, data: Vec<crate::Value>) -> Result<Table>
17
+ {
18
+ if data.len() % headers.len() != 0
19
+ {
20
+ Err(error::Error::InvalidTableDimensions)?;
21
+ }
22
+ Ok(Table { headers, data })
23
+ }
24
+ /// Create an empty table
25
+ pub fn empty() -> Table
26
+ {
27
+ Table {
28
+ headers: Default::default(),
29
+ data: Default::default(),
30
+ }
31
+ }
32
+ /// Return true is empty
33
+ pub fn is_empty(&self) -> bool
34
+ {
35
+ self.data.is_empty()
36
+ }
37
+ /// Access to the headers of the table
38
+ pub fn headers(&self) -> &Vec<String>
39
+ {
40
+ &self.headers
41
+ }
42
+ /// number of rows
43
+ pub fn rows(&self) -> usize
44
+ {
45
+ self.data.len() / self.headers.len()
46
+ }
47
+ /// number of columns
48
+ pub fn columns(&self) -> usize
49
+ {
50
+ self.headers.len()
51
+ }
52
+ /// value access
53
+ pub fn get<T>(&self, row: usize, column: usize) -> Result<&T>
54
+ where
55
+ Value: ValueTryIntoRef<T>,
56
+ {
57
+ let v = self.value(row, column)?;
58
+ v.try_into_ref()
59
+ }
60
+ /// value access
61
+ pub fn get_owned<T>(&self, row: usize, column: usize) -> Result<T>
62
+ where
63
+ Value: ValueTryIntoRef<T>,
64
+ T: Clone,
65
+ {
66
+ let v = self.value(row, column)?;
67
+ v.try_into_ref().map(T::to_owned)
68
+ }
69
+ /// value access
70
+ pub fn value(&self, row: usize, column: usize) -> Result<&Value>
71
+ {
72
+ if column > self.headers.len()
73
+ {
74
+ Err(error::Error::InvalidRange)
75
+ }
76
+ else
77
+ {
78
+ self
79
+ .data
80
+ .get(row * self.headers.len() + column)
81
+ .ok_or(error::Error::InvalidRange)
82
+ }
83
+ }
84
+ /// Create an iterator over the rows in the table
85
+ pub fn row_iter(&self) -> RowIter<'_>
86
+ {
87
+ RowIter {
88
+ data: &self.data,
89
+ columns: self.columns(),
90
+ index: 0,
91
+ row_count: self.rows(),
92
+ }
93
+ }
94
+ }
95
+
96
+ impl From<Table> for value::Value
97
+ {
98
+ fn from(val: Table) -> Self
99
+ {
100
+ let mut rows: Vec<value::Value> = Default::default();
101
+ let cl = val.headers.len();
102
+ rows.push(val.headers.into());
103
+ let mut it = val.data.into_iter();
104
+ loop
105
+ {
106
+ let first = it.next();
107
+ if let Some(first) = first
108
+ {
109
+ let mut row = Vec::with_capacity(cl);
110
+ row.push(first);
111
+ for _ in 1..cl
112
+ {
113
+ row.push(it.next().unwrap());
114
+ }
115
+ rows.push(row.into());
116
+ }
117
+ else
118
+ {
119
+ break;
120
+ }
121
+ }
122
+ rows.into()
123
+ }
124
+ }
125
+
126
+ /// View of a row
127
+ #[derive(Debug)]
128
+ pub struct RowView<'a>
129
+ {
130
+ row: &'a [value::Value], // length = columns.len()
131
+ }
132
+
133
+ impl<'a> RowView<'a>
134
+ {
135
+ /// Iterate over the value of the row view
136
+ pub fn iter(&self) -> std::slice::Iter<'a, value::Value>
137
+ {
138
+ self.row.iter()
139
+ }
140
+ /// value access
141
+ pub fn value(&self, column: usize) -> Result<&Value>
142
+ {
143
+ self.row.get(column).ok_or(error::Error::InvalidRange)
144
+ }
145
+ /// value access
146
+ pub fn get<T>(&self, column: usize) -> Result<&T>
147
+ where
148
+ Value: ValueTryIntoRef<T>,
149
+ {
150
+ let v = self.value(column)?;
151
+ v.try_into_ref()
152
+ }
153
+ /// value access
154
+ pub fn get_owned<T>(&self, column: usize) -> Result<T>
155
+ where
156
+ Value: ValueTryIntoRef<T>,
157
+ T: Clone,
158
+ {
159
+ let v = self.value(column)?;
160
+ v.try_into_ref().map(T::to_owned)
161
+ }
162
+ }
163
+
164
+ /// Iteratpr over rows of a table
165
+ pub struct RowIter<'a>
166
+ {
167
+ data: &'a Vec<value::Value>,
168
+ columns: usize,
169
+ index: usize,
170
+ row_count: usize,
171
+ }
172
+
173
+ impl<'a> Iterator for RowIter<'a>
174
+ {
175
+ type Item = RowView<'a>;
176
+
177
+ fn next(&mut self) -> Option<Self::Item>
178
+ {
179
+ if self.columns == 0
180
+ {
181
+ if self.index < self.row_count
182
+ {
183
+ self.index += 1;
184
+ Some(RowView {
185
+ row: &self.data[0..0],
186
+ })
187
+ }
188
+ else
189
+ {
190
+ None
191
+ }
192
+ }
193
+ else
194
+ {
195
+ let start = self.index * self.columns;
196
+ let end = start + self.columns;
197
+
198
+ if self.columns == 0 || end > self.data.len()
199
+ {
200
+ return None;
201
+ }
202
+
203
+ let rv = RowView {
204
+ row: &self.data[start..end],
205
+ };
206
+
207
+ self.index += 1;
208
+
209
+ Some(rv)
210
+ }
211
+ }
212
+ }
213
+
214
+ /// Convenient macro for creating tables.
215
+ ///
216
+ /// Example:
217
+ ///
218
+ /// ```rust
219
+ /// # use graphcore::{Table, table};
220
+ /// let table: Table = table!(("a", "b"), [["row0", "row0"], ["row1", "row2"]]);
221
+ /// ```
222
+ #[macro_export]
223
+ macro_rules! table {
224
+ () => (
225
+ $crate::Table::empty()
226
+ );
227
+ (($($header:expr),+ $(,)?), []) => (
228
+ $crate::Table::new(
229
+ vec![$($header.into()),+],
230
+ vec![]
231
+ ).unwrap()
232
+ );
233
+ (($($header:expr),+ $(,)?), [$([$($x:expr),+ $(,)?]),*]) => (
234
+ {
235
+ let headers = vec![$($header.into()),+];
236
+ let mut data = Vec::new();
237
+ $(
238
+ data.extend(vec![$($x.into()),+]);
239
+ )*
240
+ $crate::Table::new(headers, data).unwrap()
241
+ }
242
+ );
243
+ }
244
+
245
+ #[cfg(test)]
246
+ mod tests
247
+ {
248
+ use crate::Table;
249
+
250
+ #[test]
251
+ fn test_table_macro()
252
+ {
253
+ let tb = table!();
254
+ assert_eq!(tb, Table::empty());
255
+ let tb = table!(("a", "b"), []);
256
+ assert_eq!(tb.rows(), 0);
257
+ assert_eq!(tb.columns(), 2);
258
+ assert_eq!(*tb.headers(), vec!["a".to_string(), "b".to_string()]);
259
+ let tb = table!(("a", "b"), [[1, 2], [3, 4]]);
260
+ assert_eq!(tb.rows(), 2);
261
+ assert_eq!(tb.columns(), 2);
262
+ assert_eq!(*tb.headers(), vec!["a".to_string(), "b".to_string()]);
263
+ assert_eq!(*tb.value(0, 0).unwrap(), 1.into());
264
+ assert_eq!(*tb.value(0, 1).unwrap(), 2.into());
265
+ assert_eq!(*tb.value(1, 0).unwrap(), 3.into());
266
+ assert_eq!(*tb.value(1, 1).unwrap(), 4.into());
267
+ assert_eq!(*tb.get::<i64>(0, 0).unwrap(), 1);
268
+ assert_eq!(*tb.get::<i64>(0, 1).unwrap(), 2);
269
+ assert_eq!(*tb.get::<i64>(1, 0).unwrap(), 3);
270
+ assert_eq!(*tb.get::<i64>(1, 1).unwrap(), 4);
271
+ }
272
+ }
@@ -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
  }