gqlite 1.2.2 → 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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gqliterb/Cargo.lock +27 -20
  3. data/ext/gqliterb/Cargo.toml +3 -2
  4. data/ext/gqliterb/src/lib.rs +7 -1
  5. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +88 -33
  6. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +7 -1
  7. data/ext/gqliterb/vendor/gqlitedb/release.toml +2 -2
  8. data/ext/gqliterb/vendor/gqlitedb/src/capi.rs +24 -1
  9. data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +4 -0
  10. data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +9 -8
  11. data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +9 -0
  12. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +192 -58
  13. data/ext/gqliterb/vendor/gqlitedb/src/error.rs +8 -16
  14. data/ext/gqliterb/vendor/gqlitedb/src/functions/edge.rs +1 -1
  15. data/ext/gqliterb/vendor/gqlitedb/src/functions/math.rs +1 -1
  16. data/ext/gqliterb/vendor/gqlitedb/src/functions/node.rs +1 -1
  17. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +33 -1
  18. data/ext/gqliterb/vendor/gqlitedb/src/functions/scalar.rs +1 -1
  19. data/ext/gqliterb/vendor/gqlitedb/src/functions/string.rs +1 -1
  20. data/ext/gqliterb/vendor/gqlitedb/src/functions/value.rs +1 -1
  21. data/ext/gqliterb/vendor/gqlitedb/src/functions.rs +11 -13
  22. data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +15 -0
  23. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +21 -33
  24. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +6 -1
  25. data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +1 -2
  26. data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +10 -24
  27. data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +8 -3
  28. data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +36 -6
  29. data/ext/gqliterb/vendor/gqlitedb/src/store/redb.rs +36 -24
  30. data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +50 -18
  31. data/ext/gqliterb/vendor/gqlitedb/src/store.rs +9 -2
  32. data/ext/gqliterb/vendor/gqlitedb/src/tests/evaluators.rs +9 -9
  33. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/redb.rs +12 -5
  34. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +12 -5
  35. data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +11 -3
  36. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +54 -4
  37. data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +7 -13
  38. metadata +2 -2
@@ -113,10 +113,15 @@ pub(crate) trait Store
113
113
  &self,
114
114
  transaction: &mut Self::TransactionBox,
115
115
  name: &String,
116
- _ignore_if_exists: bool,
116
+ ignore_if_exists: bool,
117
117
  ) -> Result<()>;
118
118
  /// Delete a graph
119
- fn delete_graph(&self, transaction: &mut Self::TransactionBox, name: &String) -> Result<()>;
119
+ fn drop_graph(
120
+ &self,
121
+ transaction: &mut Self::TransactionBox,
122
+ name: &String,
123
+ if_exists: bool,
124
+ ) -> Result<()>;
120
125
  /// Create nodes and add them to a graph
121
126
  fn create_nodes<'a, T: Iterator<Item = &'a crate::graph::Node>>(
122
127
  &self,
@@ -250,6 +255,7 @@ impl SelectNodeQuery
250
255
  select_all: false,
251
256
  }
252
257
  }
258
+ #[allow(dead_code)]
253
259
  pub(crate) fn select_labels(labels: impl Into<Vec<String>>) -> Self
254
260
  {
255
261
  Self {
@@ -323,6 +329,7 @@ pub(crate) struct SelectEdgeQuery
323
329
 
324
330
  impl SelectEdgeQuery
325
331
  {
332
+ #[allow(dead_code)]
326
333
  pub(crate) fn is_select_only_keys(&self) -> bool
327
334
  {
328
335
  self.keys.is_some()
@@ -9,7 +9,7 @@ use crate::{
9
9
  fn test_evaluate_simple_create_node()
10
10
  {
11
11
  let temp_file = crate::tests::create_tmp_file();
12
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
12
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
13
13
 
14
14
  eval_program(&store, &programs::simple_create(), &Default::default()).unwrap();
15
15
  check_stats(&store, None, 1, 0, 0, 0);
@@ -19,7 +19,7 @@ fn test_evaluate_simple_create_node()
19
19
  fn test_evaluate_create_named_node()
20
20
  {
21
21
  let temp_file = crate::tests::create_tmp_file();
22
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
22
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
23
23
 
24
24
  let value = eval_program(&store, &programs::create_named_node(), &Default::default()).unwrap();
25
25
  check_stats(&store, None, 1, 0, 0, 1);
@@ -34,7 +34,7 @@ fn test_evaluate_create_named_node()
34
34
  fn test_evaluate_create_named_node_double_return()
35
35
  {
36
36
  let temp_file = crate::tests::create_tmp_file();
37
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
37
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
38
38
 
39
39
  let value = eval_program(
40
40
  &store,
@@ -54,7 +54,7 @@ fn test_evaluate_create_named_node_double_return()
54
54
  fn test_evaluate_double_with_return()
55
55
  {
56
56
  let temp_file = crate::tests::create_tmp_file();
57
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
57
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
58
58
 
59
59
  let value = eval_program(&store, &programs::double_with_return(), &Default::default()).unwrap();
60
60
  check_stats(&store, None, 0, 0, 0, 0);
@@ -66,7 +66,7 @@ fn test_evaluate_double_with_return()
66
66
  fn test_evaluate_unwind()
67
67
  {
68
68
  let temp_file = crate::tests::create_tmp_file();
69
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
69
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
70
70
 
71
71
  let value = eval_program(&store, &programs::unwind(), &Default::default()).unwrap();
72
72
  check_stats(&store, None, 0, 0, 0, 0);
@@ -78,7 +78,7 @@ fn test_evaluate_unwind()
78
78
  fn test_evaluate_match_loop()
79
79
  {
80
80
  let temp_file = crate::tests::create_tmp_file();
81
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
81
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
82
82
 
83
83
  let node = graph::Node {
84
84
  key: graph::Key { uuid: 1 },
@@ -118,7 +118,7 @@ fn test_evaluate_match_loop()
118
118
  fn test_evaluate_optional_match()
119
119
  {
120
120
  let temp_file = crate::tests::create_tmp_file();
121
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
121
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
122
122
 
123
123
  let value = eval_program(&store, &programs::optional_match(), &Default::default()).unwrap();
124
124
  check_stats(&store, None, 0, 0, 0, 0);
@@ -133,7 +133,7 @@ fn test_evaluate_optional_match()
133
133
  fn test_evaluate_match_count()
134
134
  {
135
135
  let temp_file = crate::tests::create_tmp_file();
136
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
136
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
137
137
  let function_manager = functions::Manager::new();
138
138
  let program = programs::match_count(&function_manager);
139
139
 
@@ -172,7 +172,7 @@ fn test_evaluate_match_count()
172
172
  fn test_evaluate_aggregation()
173
173
  {
174
174
  let temp_file = crate::tests::create_tmp_file();
175
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
175
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
176
176
  let function_manager = functions::Manager::new();
177
177
  let program = programs::aggregation(&function_manager);
178
178
 
@@ -1,8 +1,15 @@
1
+ #[test]
2
+ fn test_in_memory()
3
+ {
4
+ let store = crate::store::redb::Store::in_memory().unwrap();
5
+ super::test_select_nodes(store);
6
+ }
7
+
1
8
  #[test]
2
9
  fn test_graphs()
3
10
  {
4
11
  let temp_file = crate::tests::create_tmp_file();
5
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
12
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
6
13
  super::test_graphs(store);
7
14
  }
8
15
 
@@ -10,7 +17,7 @@ fn test_graphs()
10
17
  fn test_select_nodes()
11
18
  {
12
19
  let temp_file = crate::tests::create_tmp_file();
13
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
20
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
14
21
  super::test_select_nodes(store);
15
22
  }
16
23
 
@@ -18,7 +25,7 @@ fn test_select_nodes()
18
25
  fn test_update_nodes()
19
26
  {
20
27
  let temp_file = crate::tests::create_tmp_file();
21
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
28
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
22
29
  super::test_update_nodes(store);
23
30
  }
24
31
 
@@ -26,7 +33,7 @@ fn test_update_nodes()
26
33
  fn test_select_edges()
27
34
  {
28
35
  let temp_file = crate::tests::create_tmp_file();
29
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
36
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
30
37
  super::test_select_edges(store);
31
38
  }
32
39
 
@@ -34,6 +41,6 @@ fn test_select_edges()
34
41
  fn test_update_edges()
35
42
  {
36
43
  let temp_file = crate::tests::create_tmp_file();
37
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
44
+ let store = crate::store::redb::Store::open(temp_file.path()).unwrap();
38
45
  super::test_update_edges(store);
39
46
  }
@@ -1,8 +1,15 @@
1
+ #[test]
2
+ fn test_in_memory()
3
+ {
4
+ let store = crate::store::sqlite::Store::in_memory().unwrap();
5
+ super::test_select_nodes(store);
6
+ }
7
+
1
8
  #[test]
2
9
  fn test_graphs()
3
10
  {
4
11
  let temp_file = crate::tests::create_tmp_file();
5
- let store = crate::store::redb::Store::new(temp_file.path()).unwrap();
12
+ let store = crate::store::sqlite::Store::open(temp_file.path()).unwrap();
6
13
  super::test_graphs(store);
7
14
  }
8
15
 
@@ -10,7 +17,7 @@ fn test_graphs()
10
17
  fn test_select_nodes()
11
18
  {
12
19
  let temp_file = crate::tests::create_tmp_file();
13
- let store = crate::store::sqlite::Store::new(temp_file.path()).unwrap();
20
+ let store = crate::store::sqlite::Store::open(temp_file.path()).unwrap();
14
21
  super::test_select_nodes(store);
15
22
  }
16
23
 
@@ -18,7 +25,7 @@ fn test_select_nodes()
18
25
  fn test_update_nodes()
19
26
  {
20
27
  let temp_file = crate::tests::create_tmp_file();
21
- let store = crate::store::sqlite::Store::new(temp_file.path()).unwrap();
28
+ let store = crate::store::sqlite::Store::open(temp_file.path()).unwrap();
22
29
  super::test_update_nodes(store);
23
30
  }
24
31
 
@@ -26,7 +33,7 @@ fn test_update_nodes()
26
33
  fn test_select_edges()
27
34
  {
28
35
  let temp_file = crate::tests::create_tmp_file();
29
- let store = crate::store::sqlite::Store::new(temp_file.path()).unwrap();
36
+ let store = crate::store::sqlite::Store::open(temp_file.path()).unwrap();
30
37
  super::test_select_edges(store);
31
38
  }
32
39
 
@@ -34,6 +41,6 @@ fn test_select_edges()
34
41
  fn test_update_edges()
35
42
  {
36
43
  let temp_file = crate::tests::create_tmp_file();
37
- let store = crate::store::sqlite::Store::new(temp_file.path()).unwrap();
44
+ let store = crate::store::sqlite::Store::open(temp_file.path()).unwrap();
38
45
  super::test_update_edges(store);
39
46
  }
@@ -53,10 +53,10 @@ where
53
53
  vec!["default".to_string(), "test_graph".to_string()]
54
54
  );
55
55
 
56
- // Delete graph
56
+ // Drop graph
57
57
  let mut tx = store.begin_write().unwrap();
58
58
  store
59
- .delete_graph(&mut tx, &"test_graph".to_string())
59
+ .drop_graph(&mut tx, &"test_graph".to_string(), false)
60
60
  .unwrap();
61
61
  tx.close().unwrap();
62
62
 
@@ -81,11 +81,19 @@ where
81
81
  vec!["default".to_string(), "test_graph".to_string()]
82
82
  );
83
83
 
84
+ // Drop unexisting graph
84
85
  let mut tx = store.begin_write().unwrap();
85
86
  store
86
- .delete_graph(&mut tx, &"unknown".to_string())
87
+ .drop_graph(&mut tx, &"unknown".to_string(), false)
87
88
  .expect_err("Attempt at deleting unknown graph.");
88
89
  drop(tx);
90
+
91
+ // Drop unexisting graph
92
+ let mut tx = store.begin_write().unwrap();
93
+ store
94
+ .drop_graph(&mut tx, &"unknown".to_string(), true)
95
+ .unwrap();
96
+ drop(tx);
89
97
  }
90
98
 
91
99
  fn test_select_nodes<TStore>(store: TStore)
@@ -329,17 +329,20 @@ impl Add for Value
329
329
  {
330
330
  Self::Float(rhs) => Ok((lhs + rhs).into()),
331
331
  Self::Integer(rhs) => Ok((lhs + rhs as f64).into()),
332
+ Self::Null => Ok(Self::Null),
332
333
  _ => Err(RunTimeError::InvalidBinaryOperands.into()),
333
334
  },
334
335
  Self::Integer(lhs) => match rhs
335
336
  {
336
337
  Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
337
338
  Self::Integer(rhs) => Ok((lhs + rhs).into()),
339
+ Self::Null => Ok(Self::Null),
338
340
  _ => Err(RunTimeError::InvalidBinaryOperands.into()),
339
341
  },
340
342
  Self::String(lhs) => match rhs
341
343
  {
342
344
  Self::String(rhs) => Ok((lhs + &rhs).into()),
345
+ Self::Null => Ok(Self::Null),
343
346
  _ => Err(RunTimeError::InvalidBinaryOperands.into()),
344
347
  },
345
348
  }
@@ -367,12 +370,14 @@ macro_rules! impl_mdsr {
367
370
  {
368
371
  Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
369
372
  Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
373
+ Self::Null => Ok(Self::Null),
370
374
  _ => Err(RunTimeError::InvalidBinaryOperands.into()),
371
375
  },
372
376
  Self::Integer(lhs) => match rhs
373
377
  {
374
378
  Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
375
379
  Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
380
+ Self::Null => Ok(Self::Null),
376
381
  _ => Err(RunTimeError::InvalidBinaryOperands.into()),
377
382
  },
378
383
  }
@@ -386,6 +391,42 @@ impl_mdsr!(Sub, sub);
386
391
  impl_mdsr!(Div, div);
387
392
  impl_mdsr!(Rem, rem);
388
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
+
389
430
  impl Neg for Value
390
431
  {
391
432
  type Output = crate::Result<Value>;
@@ -435,7 +476,7 @@ impl std::fmt::Display for Value
435
476
  }
436
477
 
437
478
  /// Trait to return a reference to the underlying type
438
- pub(crate) trait ValueTryIntoRef<T>
479
+ pub trait ValueTryIntoRef<T>
439
480
  {
440
481
  /// Return a reference to T
441
482
  fn try_into_ref<'a>(&'a self) -> Result<&'a T, Error>;
@@ -511,6 +552,7 @@ impl_to_value!(f64, Float);
511
552
  impl_to_value!(String, String);
512
553
  impl_to_value!(graph::Node, Node);
513
554
  impl_to_value!(graph::Edge, Edge);
555
+ impl_to_value!(graph::Path, Path);
514
556
  impl_to_value!(Vec<Value>, Array);
515
557
  impl_to_value!(ValueMap, Map);
516
558
 
@@ -522,13 +564,21 @@ impl Into<Value> for &str
522
564
  }
523
565
  }
524
566
 
525
- #[cfg(test)]
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]
526
576
  macro_rules! array {
527
577
  () => (
528
- $crate::value::Value::Array(Default::default())
578
+ $crate::Value::Array(Default::default())
529
579
  );
530
580
  ($($x:expr),+ $(,)?) => (
531
- $crate::value::Value::Array(
581
+ $crate::Value::Array(
532
582
  vec![$($x.into()),+]
533
583
  )
534
584
  );
@@ -11,6 +11,7 @@ pub(crate) trait RowInterface: Debug
11
11
  {
12
12
  Ok(self.get(index)?.to_owned())
13
13
  }
14
+ #[cfg(test)]
14
15
  fn len(&self) -> usize;
15
16
  }
16
17
 
@@ -97,6 +98,7 @@ impl RowInterface for Row
97
98
  .into()
98
99
  })
99
100
  }
101
+ #[cfg(test)]
100
102
  fn len(&self) -> usize
101
103
  {
102
104
  self.values.len()
@@ -155,7 +157,6 @@ impl FromIterator<value::Value> for Row
155
157
  pub(crate) trait Header
156
158
  {
157
159
  fn columns(&self) -> usize;
158
- fn titles(&self) -> Option<Vec<String>>;
159
160
  }
160
161
 
161
162
  impl Header for usize
@@ -164,10 +165,6 @@ impl Header for usize
164
165
  {
165
166
  *self
166
167
  }
167
- fn titles(&self) -> Option<Vec<String>>
168
- {
169
- None
170
- }
171
168
  }
172
169
 
173
170
  impl Header for Vec<String>
@@ -176,10 +173,6 @@ impl Header for Vec<String>
176
173
  {
177
174
  self.len()
178
175
  }
179
- fn titles(&self) -> Option<Vec<String>>
180
- {
181
- Some(self.clone())
182
- }
183
176
  }
184
177
 
185
178
  #[derive(Debug)]
@@ -256,12 +249,14 @@ where
256
249
  Ok(())
257
250
  }
258
251
 
252
+ #[allow(dead_code)]
259
253
  pub fn row_count(&self) -> usize
260
254
  {
261
255
  self.row_count
262
256
  }
263
257
 
264
258
  /// Create a RowView into a specific row
259
+ #[allow(dead_code)]
265
260
  pub fn row_view(&self, row_index: usize) -> Option<RowView<'_>>
266
261
  {
267
262
  if self.header.columns() == 0 && row_index >= self.row_count
@@ -302,10 +297,6 @@ where
302
297
  index: 0,
303
298
  }
304
299
  }
305
- pub(crate) fn first_row(&self) -> Option<RowView>
306
- {
307
- self.row_view(0)
308
- }
309
300
  pub(crate) fn remove_first_rows(&mut self, n: usize)
310
301
  {
311
302
  let n = n * self.header.columns();
@@ -334,6 +325,7 @@ pub(crate) struct RowView<'a>
334
325
 
335
326
  impl<'a> RowView<'a>
336
327
  {
328
+ #[allow(dead_code)]
337
329
  /// Create an owned Row by cloning the values in this row view
338
330
  pub fn to_row(&self) -> Row
339
331
  {
@@ -341,6 +333,7 @@ impl<'a> RowView<'a>
341
333
  values: self.row.to_vec(),
342
334
  }
343
335
  }
336
+ #[allow(dead_code)]
344
337
  /// Create an owned Row by cloning the values in this row view, and extend it to the given size
345
338
  pub fn to_extended_row(&self, length: usize) -> Result<Row>
346
339
  {
@@ -363,6 +356,7 @@ impl<'a> RowInterface for RowView<'a>
363
356
  .into()
364
357
  })
365
358
  }
359
+ #[cfg(test)]
366
360
  fn len(&self) -> usize
367
361
  {
368
362
  self.row.len()
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gqlite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyrille Berger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-26 00:00:00.000000000 Z
11
+ date: 2025-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys