yerba 0.5.0-aarch64-linux-gnu → 0.6.0-aarch64-linux-gnu

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc22173aad9bed5d4dabd219b9718e9bf213f466c9e85f6d24f5f0bc64069abd
4
- data.tar.gz: cbb0d8b0204943b934f14e71a79794da8fa4d61f3b53c3e3f7816092e37e5059
3
+ metadata.gz: 25f1b44c80d2fea571408d3db9e17d82480f3ec0bc9ba7c44f7facc374a7ff45
4
+ data.tar.gz: 0b6c9c732054bfe5c95c22587a3d0900128b533a2fb5445ebe7847ad17a6bad6
5
5
  SHA512:
6
- metadata.gz: 99710aedf80e7fcb22fde5e46b8747af622663dec9610caf20ce823d79124141ac7ac656869bf7da3e72e1c94b4e83f9b4173ad4d6ec6d55215869c2f92343e8
7
- data.tar.gz: e10141d157b0fe48f0a2472f4c9cd8085b5ec40b0921ea744243dea1431d3b38bce6bb07909b9348042e16dfea9f013affbd7b43d986fb5673a55f4cab647673
6
+ metadata.gz: 15c96de98439438601d7c507aed217b0b96dc58afadf532d590ff1fc1d9650f65489a57b520c33878a82c60686e78f44955d5b940158cfbe2367613b5a1b141b
7
+ data.tar.gz: d7b3a4bf8f4b8943a0454845ab7a0c2ef9ea021b6d410e7667beecec461b7d12453b0437823b46556a7dabab7d2fd7730dca4fe01685bfa7c62fc03ec6cb23bf
data/README.md CHANGED
@@ -47,7 +47,7 @@ Use `yerba` as a library in your Rust project:
47
47
 
48
48
  ```toml
49
49
  [dependencies]
50
- yerba = "0.4"
50
+ yerba = "0.5"
51
51
  ```
52
52
 
53
53
  ```rust
@@ -843,31 +843,7 @@ document.to_s
843
843
 
844
844
  ## Development
845
845
 
846
- After checking out the repo, run `bundle install` to install Ruby dependencies, then `bundle exec rake test` to run the test suite.
847
-
848
- ### Building from source
849
-
850
- The Rust core is in the `rust/` directory, with a workspace `Cargo.toml` at the root so all cargo commands work from the project root:
851
-
852
- ```bash
853
- cargo build
854
- cargo test
855
- ```
856
-
857
- The C extension (for the Ruby API) is compiled via `ext/yerba/extconf.rb` which invokes `cargo build` and links against the resulting static library. Running `bundle exec rake compile` will build both the Rust library and the C extension.
858
-
859
- ### Running the CLI locally
860
-
861
- ```bash
862
- cargo run -- get config.yml "database.host"
863
- ```
864
-
865
- Or build a release binary:
866
-
867
- ```bash
868
- cargo build --release
869
- ./target/release/yerba --help
870
- ```
846
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to set up the repo locally, run tests, and contribute.
871
847
 
872
848
  ## License
873
849
 
Binary file
@@ -90,6 +90,18 @@ struct YerbaResult yerba_document_set_quote_style(struct Document *document,
90
90
  const char *path,
91
91
  const char *style);
92
92
 
93
+ char *yerba_document_get_collection_style(const struct Document *document, const char *path);
94
+
95
+ struct YerbaResult yerba_document_set_collection_style(struct Document *document,
96
+ const char *path,
97
+ const char *style);
98
+
99
+ char *yerba_document_get_sequence_indent(const struct Document *document, const char *path);
100
+
101
+ struct YerbaResult yerba_document_set_sequence_indent(struct Document *document,
102
+ const char *path,
103
+ const char *style);
104
+
93
105
  bool yerba_document_evaluate_condition(const struct Document *document,
94
106
  const char *parent_path,
95
107
  const char *condition);
data/ext/yerba/yerba.c CHANGED
@@ -374,6 +374,76 @@ static VALUE document_set_quote_style(VALUE self, VALUE path, VALUE style) {
374
374
  return self;
375
375
  }
376
376
 
377
+ /* document.get_collection_style(path) → :flow, :block, or nil */
378
+ static VALUE document_get_collection_style(VALUE self, VALUE path) {
379
+ struct Document *document = get_document(self);
380
+ char *style = yerba_document_get_collection_style(document, StringValueCStr(path));
381
+
382
+ if (style == NULL) return Qnil;
383
+
384
+ VALUE symbol = ID2SYM(rb_intern(style));
385
+
386
+ yerba_string_free(style);
387
+
388
+ return symbol;
389
+ }
390
+
391
+ /* document.set_collection_style(path, style) */
392
+ static VALUE document_set_collection_style(VALUE self, VALUE path, VALUE style) {
393
+ struct Document *document = get_document(self);
394
+
395
+ const char *style_string;
396
+
397
+ if (RB_TYPE_P(style, T_SYMBOL)) {
398
+ style_string = rb_id2name(SYM2ID(style));
399
+ } else if (RB_TYPE_P(style, T_STRING)) {
400
+ style_string = StringValueCStr(style);
401
+ } else {
402
+ rb_raise(rb_eError, "Invalid collection style (expected Symbol or String)");
403
+ }
404
+
405
+ YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(path), style_string);
406
+
407
+ check_result(result);
408
+
409
+ return self;
410
+ }
411
+
412
+ /* document.get_sequence_indent(path) → :compact, :indented, or nil */
413
+ static VALUE document_get_sequence_indent(VALUE self, VALUE path) {
414
+ struct Document *document = get_document(self);
415
+ char *style = yerba_document_get_sequence_indent(document, StringValueCStr(path));
416
+
417
+ if (style == NULL) return Qnil;
418
+
419
+ VALUE symbol = ID2SYM(rb_intern(style));
420
+
421
+ yerba_string_free(style);
422
+
423
+ return symbol;
424
+ }
425
+
426
+ /* document.set_sequence_indent(path, style) */
427
+ static VALUE document_set_sequence_indent(VALUE self, VALUE path, VALUE style) {
428
+ struct Document *document = get_document(self);
429
+
430
+ const char *style_string;
431
+
432
+ if (RB_TYPE_P(style, T_SYMBOL)) {
433
+ style_string = rb_id2name(SYM2ID(style));
434
+ } else if (RB_TYPE_P(style, T_STRING)) {
435
+ style_string = StringValueCStr(style);
436
+ } else {
437
+ rb_raise(rb_eError, "Invalid sequence indent style (expected Symbol or String)");
438
+ }
439
+
440
+ YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(path), style_string);
441
+
442
+ check_result(result);
443
+
444
+ return self;
445
+ }
446
+
377
447
  /* document.condition?(condition, path: "") */
378
448
  static VALUE document_condition_p(int argc, VALUE *argv, VALUE self) {
379
449
  VALUE condition, opts;
@@ -965,6 +1035,10 @@ void Init_yerba(void) {
965
1035
  rb_define_method(rb_cDocument, "resolve_selectors", document_resolve_selectors, 1);
966
1036
  rb_define_method(rb_cDocument, "get_quote_style", document_get_quote_style, 1);
967
1037
  rb_define_method(rb_cDocument, "set_quote_style", document_set_quote_style, 2);
1038
+ rb_define_method(rb_cDocument, "get_collection_style", document_get_collection_style, 1);
1039
+ rb_define_method(rb_cDocument, "set_collection_style", document_set_collection_style, 2);
1040
+ rb_define_method(rb_cDocument, "get_sequence_indent", document_get_sequence_indent, 1);
1041
+ rb_define_method(rb_cDocument, "set_sequence_indent", document_set_sequence_indent, 2);
968
1042
  rb_define_method(rb_cDocument, "exists?", document_exists_p, 1);
969
1043
  rb_define_method(rb_cDocument, "valid_selector?", document_valid_selector_p, 1);
970
1044
  rb_define_method(rb_cDocument, "condition?", document_condition_p, -1);
Binary file
Binary file
Binary file
Binary file
@@ -14,5 +14,66 @@ module Yerba
14
14
  value.to_s
15
15
  end
16
16
  end
17
+
18
+ def self.to_yaml_value(value)
19
+ case value
20
+ when Array
21
+ return "[]" if value.empty?
22
+
23
+ items = value.map { |item| to_yaml_value(item) }
24
+
25
+ "[#{items.join(", ")}]"
26
+ when Hash
27
+ return "{}" if value.empty?
28
+
29
+ pairs = value.map { |key, value| "#{key}: #{to_yaml_value(value)}" }
30
+
31
+ "{#{pairs.join(", ")}}"
32
+ when true then "true"
33
+ when false then "false"
34
+ when nil then "null"
35
+ else value.to_s
36
+ end
37
+ end
38
+
39
+ def self.to_block_yaml_value(value, indent = 0)
40
+ prefix = " " * indent
41
+
42
+ case value
43
+ when Array
44
+ return "[]" if value.empty?
45
+
46
+ value.map { |item|
47
+ if item.is_a?(Hash)
48
+ inner = to_block_yaml_value(item, indent + 1)
49
+ "#{prefix}- #{inner.lstrip}"
50
+ else
51
+ "#{prefix}- #{to_scalar_value(item)}"
52
+ end
53
+ }.join("\n")
54
+ when Hash
55
+ return "{}" if value.empty?
56
+
57
+ value.map { |key, value|
58
+ if value.is_a?(Hash) || value.is_a?(Array)
59
+ inner = to_block_yaml_value(value, indent + 1)
60
+ "#{prefix}#{key}:\n#{inner}"
61
+ else
62
+ "#{prefix}#{key}: #{to_scalar_value(value)}"
63
+ end
64
+ }.join("\n")
65
+ else
66
+ to_scalar_value(value)
67
+ end
68
+ end
69
+
70
+ def self.to_scalar_value(value)
71
+ case value
72
+ when true then "true"
73
+ when false then "false"
74
+ when nil then "null"
75
+ else value.to_s
76
+ end
77
+ end
17
78
  end
18
79
  end
data/lib/yerba/map.rb CHANGED
@@ -25,24 +25,44 @@ module Yerba
25
25
  end
26
26
 
27
27
  def []=(key, value)
28
+ set(key, value)
29
+ end
30
+
31
+ def set(key, value, style: nil)
28
32
  if connected?
29
33
  new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
30
-
31
- if document.exists?(new_path)
32
- document.set(new_path, value)
34
+ coerced = coerce_value(value, style: style)
35
+ is_block_value = coerced.is_a?(String) && (coerced.include?("\n") || coerced.start_with?("- "))
36
+
37
+ if document.exists?(new_path) && is_block_value
38
+ # Block-style collections can't replace a scalar via set().
39
+ # Delete the key and re-insert at the same position.
40
+ all_keys = keys
41
+ key_index = all_keys.index(key.to_s)
42
+ after_key = key_index&.positive? ? all_keys[key_index - 1] : nil
43
+
44
+ document.delete(new_path)
45
+
46
+ if after_key
47
+ document.insert(new_path, coerced, after: after_key)
48
+ else
49
+ document.insert(new_path, coerced)
50
+ end
51
+ elsif document.exists?(new_path)
52
+ document.set(new_path, coerced)
33
53
  else
34
- document.insert(new_path, value)
54
+ document.insert(new_path, coerced)
35
55
  end
36
56
  else
37
57
  @data[key] = value
38
58
  end
39
59
  end
40
60
 
41
- def insert(key, value, before: nil, after: nil)
61
+ def insert(key, value, before: nil, after: nil, style: nil)
42
62
  if connected?
43
63
  new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
44
64
 
45
- document.insert(new_path, value, before: before, after: after)
65
+ document.insert(new_path, coerce_value(value, style: style), before: before, after: after)
46
66
  else
47
67
  @data[key] = value
48
68
  end
@@ -165,6 +185,16 @@ module Yerba
165
185
  end
166
186
  end
167
187
 
188
+ def collection_style
189
+ @collection_style || document&.get_collection_style(@selector)
190
+ end
191
+
192
+ def collection_style=(style)
193
+ document&.set_collection_style(@selector, style)
194
+
195
+ @collection_style = style
196
+ end
197
+
168
198
  private
169
199
 
170
200
  def format_value(value)
@@ -174,5 +204,19 @@ module Yerba
174
204
  else value.to_s
175
205
  end
176
206
  end
207
+
208
+ def coerce_value(value, style: nil)
209
+ case value
210
+ when Array, Hash
211
+ resolved_style = style || :block
212
+
213
+ if resolved_style == :flow
214
+ Formatting.to_yaml_value(value)
215
+ else
216
+ Formatting.to_block_yaml_value(value)
217
+ end
218
+ else value
219
+ end
220
+ end
177
221
  end
178
222
  end
@@ -293,6 +293,26 @@ module Yerba
293
293
  end
294
294
  end
295
295
 
296
+ def collection_style
297
+ @collection_style || document&.get_collection_style(@selector)
298
+ end
299
+
300
+ def collection_style=(style)
301
+ document&.set_collection_style(@selector, style)
302
+
303
+ @collection_style = style
304
+ end
305
+
306
+ def sequence_indent
307
+ @sequence_indent || document&.get_sequence_indent(@selector)
308
+ end
309
+
310
+ def sequence_indent=(style)
311
+ document&.set_sequence_indent(@selector, style)
312
+
313
+ @sequence_indent = style
314
+ end
315
+
296
316
  private
297
317
 
298
318
  def dig_into(hash, path)
data/lib/yerba/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Yerba
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
data/rust/Cargo.lock CHANGED
@@ -739,6 +739,12 @@ version = "0.2.186"
739
739
  source = "registry+https://github.com/rust-lang/crates.io-index"
740
740
  checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
741
741
 
742
+ [[package]]
743
+ name = "libyaml-rs"
744
+ version = "0.3.0"
745
+ source = "registry+https://github.com/rust-lang/crates.io-index"
746
+ checksum = "2e126dda6f34391ab7b444f9922055facc83c07a910da3eb16f1e4d9c45dc777"
747
+
742
748
  [[package]]
743
749
  name = "linux-raw-sys"
744
750
  version = "0.12.1"
@@ -1198,19 +1204,6 @@ dependencies = [
1198
1204
  "serde",
1199
1205
  ]
1200
1206
 
1201
- [[package]]
1202
- name = "serde_yaml"
1203
- version = "0.9.34+deprecated"
1204
- source = "registry+https://github.com/rust-lang/crates.io-index"
1205
- checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
1206
- dependencies = [
1207
- "indexmap",
1208
- "itoa",
1209
- "ryu",
1210
- "serde",
1211
- "unsafe-libyaml",
1212
- ]
1213
-
1214
1207
  [[package]]
1215
1208
  name = "slab"
1216
1209
  version = "0.4.12"
@@ -1441,12 +1434,6 @@ version = "0.2.6"
1441
1434
  source = "registry+https://github.com/rust-lang/crates.io-index"
1442
1435
  checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
1443
1436
 
1444
- [[package]]
1445
- name = "unsafe-libyaml"
1446
- version = "0.2.11"
1447
- source = "registry+https://github.com/rust-lang/crates.io-index"
1448
- checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
1449
-
1450
1437
  [[package]]
1451
1438
  name = "url"
1452
1439
  version = "2.5.8"
@@ -1770,9 +1757,22 @@ dependencies = [
1770
1757
  "winnow",
1771
1758
  ]
1772
1759
 
1760
+ [[package]]
1761
+ name = "yaml_serde"
1762
+ version = "0.10.4"
1763
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1764
+ checksum = "08c7c1b1a6a7c8a6b2741a6c21a4f8918e51899b111cfa08d1288202656e3975"
1765
+ dependencies = [
1766
+ "indexmap",
1767
+ "itoa",
1768
+ "libyaml-rs",
1769
+ "ryu",
1770
+ "serde",
1771
+ ]
1772
+
1773
1773
  [[package]]
1774
1774
  name = "yerba"
1775
- version = "0.5.0"
1775
+ version = "0.6.0"
1776
1776
  dependencies = [
1777
1777
  "cbindgen",
1778
1778
  "clap",
@@ -1783,9 +1783,9 @@ dependencies = [
1783
1783
  "rowan",
1784
1784
  "serde",
1785
1785
  "serde_json",
1786
- "serde_yaml",
1787
1786
  "tempfile",
1788
1787
  "yaml_parser",
1788
+ "yaml_serde",
1789
1789
  ]
1790
1790
 
1791
1791
  [[package]]
data/rust/Cargo.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "yerba"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  edition = "2021"
5
5
  authors = ["Marco Roth <marco.roth@intergga.ch>"]
6
6
  description = "YAML Editing and Refactoring with Better Accuracy"
@@ -24,7 +24,7 @@ yaml_parser = "0.3"
24
24
  rowan = "0.16"
25
25
  glob = "0.3"
26
26
  serde = { version = "1", features = ["derive"] }
27
- serde_yaml = "0.9"
27
+ yaml_serde = "0.10"
28
28
  serde_json = { version = "1", features = ["preserve_order"] }
29
29
  clap = { version = "4", features = ["derive"] }
30
30
  indoc = "2"
@@ -112,7 +112,7 @@ impl Args {
112
112
  }
113
113
  }
114
114
 
115
- let (values, selectors, lines): (Vec<serde_yaml::Value>, Vec<String>, Vec<usize>) = if select_fields.is_some() {
115
+ let (values, selectors, lines): (Vec<yaml_serde::Value>, Vec<String>, Vec<usize>) = if select_fields.is_some() {
116
116
  if let Some(condition) = &normalized_condition {
117
117
  let triples = document.filter_with_selectors(&search_path_string, condition);
118
118
  let (values, rest): (Vec<_>, Vec<_>) = triples.into_iter().map(|(v, s, l)| (v, (s, l))).unzip();
@@ -116,11 +116,11 @@ impl Args {
116
116
  }
117
117
  }
118
118
 
119
- fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mut BTreeMap<String, SelectorInfo>, counter: &mut usize) {
119
+ fn collect_selectors(value: &yaml_serde::Value, prefix: &str, selectors: &mut BTreeMap<String, SelectorInfo>, counter: &mut usize) {
120
120
  match value {
121
- serde_yaml::Value::Mapping(map) => {
121
+ yaml_serde::Value::Mapping(map) => {
122
122
  for (key, child) in map {
123
- if let serde_yaml::Value::String(key_string) = key {
123
+ if let yaml_serde::Value::String(key_string) = key {
124
124
  let selector = if prefix.is_empty() {
125
125
  key_string.clone()
126
126
  } else {
@@ -138,7 +138,7 @@ fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mut BT
138
138
  }
139
139
  }
140
140
 
141
- serde_yaml::Value::Sequence(sequence) => {
141
+ yaml_serde::Value::Sequence(sequence) => {
142
142
  let bracket_prefix = format!("{}[]", prefix);
143
143
 
144
144
  let entry = selectors.entry(bracket_prefix.clone()).or_default();
@@ -329,7 +329,7 @@ impl Args {
329
329
  .map(|item| {
330
330
  if by_is_scalar {
331
331
  match item {
332
- serde_yaml::Value::String(string) => string.clone(),
332
+ yaml_serde::Value::String(string) => string.clone(),
333
333
  _ => serde_json::to_string(&yerba::json::yaml_to_json(item)).unwrap_or_default(),
334
334
  }
335
335
  } else {
@@ -1,7 +1,7 @@
1
1
  use super::*;
2
2
 
3
3
  impl Document {
4
- pub fn filter(&self, dot_path: &str, condition: &str) -> Vec<serde_yaml::Value> {
4
+ pub fn filter(&self, dot_path: &str, condition: &str) -> Vec<yaml_serde::Value> {
5
5
  self
6
6
  .navigate_all_compact(dot_path)
7
7
  .iter()
@@ -10,7 +10,7 @@ impl Document {
10
10
  .collect()
11
11
  }
12
12
 
13
- pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(serde_yaml::Value, String, usize)> {
13
+ pub fn filter_with_selectors(&self, dot_path: &str, condition: &str) -> Vec<(yaml_serde::Value, String, usize)> {
14
14
  let source = self.root.text().to_string();
15
15
 
16
16
  self
@@ -35,17 +35,74 @@ impl Document {
35
35
  pub fn delete(&mut self, dot_path: &str) -> Result<(), YerbaError> {
36
36
  Self::validate_path(dot_path)?;
37
37
 
38
- let (parent_path, last_key) = dot_path.rsplit_once('.').unwrap_or(("", dot_path));
39
- let parent_node = self.navigate(parent_path)?;
38
+ let selector = crate::selector::Selector::parse(dot_path);
39
+ let segments = selector.segments();
40
+ let last_segment = segments.last().ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
41
+ let parent_path = selector.parent_path();
40
42
 
41
- let map = parent_node
42
- .descendants()
43
- .find_map(BlockMap::cast)
44
- .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
43
+ match last_segment {
44
+ crate::selector::SelectorSegment::Key(last_key) => {
45
+ let has_wildcard = selector.has_wildcard() || selector.has_brackets();
46
+
47
+ if parent_path.is_empty() && !has_wildcard {
48
+ let parent_node = self.navigate(&parent_path)?;
49
+ let map = parent_node
50
+ .descendants()
51
+ .find_map(BlockMap::cast)
52
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
53
+
54
+ let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
55
+
56
+ return self.remove_map_entry(&entry);
57
+ }
58
+
59
+ let parent_nodes = self.navigate_all_compact(&parent_path);
60
+
61
+ if parent_nodes.is_empty() {
62
+ if has_wildcard {
63
+ return Ok(());
64
+ }
65
+
66
+ return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
67
+ }
68
+
69
+ if parent_nodes.len() == 1 && !has_wildcard {
70
+ let map = parent_nodes[0]
71
+ .descendants()
72
+ .find_map(BlockMap::cast)
73
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
45
74
 
46
- let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
75
+ let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
47
76
 
48
- self.remove_node(entry.syntax())
77
+ return self.remove_map_entry(&entry);
78
+ }
79
+
80
+ let mut ranges: Vec<TextRange> = Vec::new();
81
+
82
+ for parent_node in &parent_nodes {
83
+ if let Some(map) = parent_node.descendants().find_map(BlockMap::cast) {
84
+ if let Some(entry) = find_entry_by_key(&map, last_key) {
85
+ ranges.push(removal_range(entry.syntax()));
86
+ }
87
+ }
88
+ }
89
+
90
+ if ranges.is_empty() {
91
+ return Ok(());
92
+ }
93
+
94
+ ranges.reverse();
95
+
96
+ for range in ranges {
97
+ self.apply_edit(range, "")?;
98
+ }
99
+
100
+ Ok(())
101
+ }
102
+
103
+ crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
104
+ crate::selector::SelectorSegment::AllItems => Err(YerbaError::SelectorNotFound(dot_path.to_string())),
105
+ }
49
106
  }
50
107
 
51
108
  pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {