yerba 0.5.0-x86_64-linux-gnu → 0.5.1-x86_64-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: 497a769ee07b1e766ff7e0f991212be8268e475d1e5a9cc882e9f62845390401
4
- data.tar.gz: d7e66c881d9547477d3ea8ebc232e52141a561a063179cf3534ad9c0090e1ad2
3
+ metadata.gz: 19b6906bd8f2db29860e1dfe1cb78a80d26b8cfa30ce01a9b76de7be22568a0c
4
+ data.tar.gz: 618eea79126aa8456337d0c3a905dd0d782510457b16bb368fa70e1de4177df3
5
5
  SHA512:
6
- metadata.gz: 5fc61b863455ba54bb41f63da74d32114e62cc54c2f467534ce6da158b3c8ef820defe227de73179f8b013b9ec4d1824ca8c850f7538f7d0305b215c944d2279
7
- data.tar.gz: 6d6a96b09dc0536f5704e43da759b75c0404d60c89d7ec6691bc1d3313d7f9ac0cfa755836de18dfcf224a57ca42f0afdfb19303a661ee3fc3c8b0e19d20f3a1
6
+ metadata.gz: a49b141053cd6cc9e6803a914a9d4cd443e376b59319e5484b2c9bf139b245c7bf7be888739d179e5fb14dcd7931f95e878d1430ebd2694c25354d08fe5625ed
7
+ data.tar.gz: 959d1cd010d792c74b4ad0d45c815e30b3b76fd5becb7d78a1c64736ded4e41b08c8e2049f7e79912c7675f2c479656f868180b0567388a9c1864a41639f8f18
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
Binary file
Binary file
Binary file
Binary file
Binary file
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.5.1"
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.5.1"
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.5.1"
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,61 @@ 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
+ let parent_nodes = self.navigate_all_compact(&parent_path);
47
+
48
+ if parent_nodes.is_empty() {
49
+ if has_wildcard {
50
+ return Ok(());
51
+ }
52
+
53
+ return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
54
+ }
55
+
56
+ if parent_nodes.len() == 1 && !has_wildcard {
57
+ let map = parent_nodes[0]
58
+ .descendants()
59
+ .find_map(BlockMap::cast)
60
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
61
+
62
+ let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
63
+
64
+ return self.remove_node(entry.syntax());
65
+ }
45
66
 
46
- let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
67
+ let mut ranges: Vec<TextRange> = Vec::new();
47
68
 
48
- self.remove_node(entry.syntax())
69
+ for parent_node in &parent_nodes {
70
+ if let Some(map) = parent_node.descendants().find_map(BlockMap::cast) {
71
+ if let Some(entry) = find_entry_by_key(&map, last_key) {
72
+ ranges.push(removal_range(entry.syntax()));
73
+ }
74
+ }
75
+ }
76
+
77
+ if ranges.is_empty() {
78
+ return Ok(());
79
+ }
80
+
81
+ ranges.reverse();
82
+
83
+ for range in ranges {
84
+ self.apply_edit(range, "")?;
85
+ }
86
+
87
+ Ok(())
88
+ }
89
+
90
+ crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
91
+ crate::selector::SelectorSegment::AllItems => Err(YerbaError::SelectorNotFound(dot_path.to_string())),
92
+ }
49
93
  }
50
94
 
51
95
  pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
@@ -278,7 +278,7 @@ impl Document {
278
278
  .collect()
279
279
  }
280
280
 
281
- pub fn get_value(&self, dot_path: &str) -> Option<serde_yaml::Value> {
281
+ pub fn get_value(&self, dot_path: &str) -> Option<yaml_serde::Value> {
282
282
  if dot_path.is_empty() {
283
283
  return Some(node_to_yaml_value(&self.root));
284
284
  }
@@ -292,15 +292,15 @@ impl Document {
292
292
  return None;
293
293
  }
294
294
 
295
- let values: Vec<serde_yaml::Value> = padded
295
+ let values: Vec<yaml_serde::Value> = padded
296
296
  .iter()
297
297
  .map(|maybe_node| match maybe_node {
298
298
  Some(node) => node_to_yaml_value(node),
299
- None => serde_yaml::Value::Null,
299
+ None => yaml_serde::Value::Null,
300
300
  })
301
301
  .collect();
302
302
 
303
- Some(serde_yaml::Value::Sequence(values))
303
+ Some(yaml_serde::Value::Sequence(values))
304
304
  } else {
305
305
  let nodes = self.navigate_all_compact(dot_path);
306
306
 
@@ -312,13 +312,13 @@ impl Document {
312
312
  return Some(node_to_yaml_value(&nodes[0]));
313
313
  }
314
314
 
315
- let values: Vec<serde_yaml::Value> = nodes.iter().map(node_to_yaml_value).collect();
315
+ let values: Vec<yaml_serde::Value> = nodes.iter().map(node_to_yaml_value).collect();
316
316
 
317
- Some(serde_yaml::Value::Sequence(values))
317
+ Some(yaml_serde::Value::Sequence(values))
318
318
  }
319
319
  }
320
320
 
321
- pub fn get_values(&self, dot_path: &str) -> Vec<serde_yaml::Value> {
321
+ pub fn get_values(&self, dot_path: &str) -> Vec<yaml_serde::Value> {
322
322
  let parsed = crate::selector::Selector::parse(dot_path);
323
323
 
324
324
  if parsed.has_wildcard() {
@@ -327,7 +327,7 @@ impl Document {
327
327
  .iter()
328
328
  .map(|maybe_node| match maybe_node {
329
329
  Some(node) => node_to_yaml_value(node),
330
- None => serde_yaml::Value::Null,
330
+ None => yaml_serde::Value::Null,
331
331
  })
332
332
  .collect()
333
333
  } else {
@@ -22,9 +22,9 @@ impl Document {
22
22
  }
23
23
  }
24
24
 
25
- if let Some(serde_yaml::Value::Sequence(sequence)) = self.get_value(dot_path).as_ref() {
26
- if let Some(serde_yaml::Value::Mapping(map)) = sequence.first() {
27
- if let Some((serde_yaml::Value::String(key_name), _)) = map.iter().next() {
25
+ if let Some(yaml_serde::Value::Sequence(sequence)) = self.get_value(dot_path).as_ref() {
26
+ if let Some(yaml_serde::Value::Mapping(map)) = sequence.first() {
27
+ if let Some((yaml_serde::Value::String(key_name), _)) = map.iter().next() {
28
28
  let deep_path = if dot_path.is_empty() {
29
29
  format!("[].{}", key_name)
30
30
  } else {
@@ -445,11 +445,11 @@ pub(crate) fn compute_location(source: &str, start_offset: usize, end_offset: us
445
445
  }
446
446
  }
447
447
 
448
- pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mut Vec<String>) {
448
+ pub fn collect_selectors(value: &yaml_serde::Value, prefix: &str, selectors: &mut Vec<String>) {
449
449
  match value {
450
- serde_yaml::Value::Mapping(map) => {
450
+ yaml_serde::Value::Mapping(map) => {
451
451
  for (key, child) in map {
452
- if let serde_yaml::Value::String(key_string) = key {
452
+ if let yaml_serde::Value::String(key_string) = key {
453
453
  let selector = if prefix.is_empty() {
454
454
  key_string.clone()
455
455
  } else {
@@ -462,7 +462,7 @@ pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mu
462
462
  }
463
463
  }
464
464
 
465
- serde_yaml::Value::Sequence(sequence) => {
465
+ yaml_serde::Value::Sequence(sequence) => {
466
466
  let bracket_prefix = format!("{}[]", prefix);
467
467
  selectors.push(bracket_prefix.clone());
468
468
 
@@ -475,21 +475,21 @@ pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mu
475
475
  }
476
476
  }
477
477
 
478
- pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
478
+ pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> yaml_serde::Value {
479
479
  if let Some(sequence) = node.descendants().find_map(BlockSeq::cast) {
480
480
  let map_position = node.descendants().find_map(BlockMap::cast).map(|map| map.syntax().text_range().start());
481
481
 
482
482
  let sequence_position = sequence.syntax().text_range().start();
483
483
 
484
484
  if map_position.is_none() || sequence_position <= map_position.unwrap() {
485
- let values: Vec<serde_yaml::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
485
+ let values: Vec<yaml_serde::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
486
486
 
487
- return serde_yaml::Value::Sequence(values);
487
+ return yaml_serde::Value::Sequence(values);
488
488
  }
489
489
  }
490
490
 
491
491
  if let Some(map) = node.descendants().find_map(BlockMap::cast) {
492
- let mut mapping = serde_yaml::Mapping::new();
492
+ let mut mapping = yaml_serde::Mapping::new();
493
493
 
494
494
  for entry in map.entries() {
495
495
  let key = entry.key().and_then(|key_node| extract_scalar_text(key_node.syntax())).unwrap_or_default();
@@ -497,18 +497,18 @@ pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
497
497
  let value = entry
498
498
  .value()
499
499
  .map(|value_node| node_to_yaml_value(value_node.syntax()))
500
- .unwrap_or(serde_yaml::Value::Null);
500
+ .unwrap_or(yaml_serde::Value::Null);
501
501
 
502
- mapping.insert(serde_yaml::Value::String(key), value);
502
+ mapping.insert(yaml_serde::Value::String(key), value);
503
503
  }
504
504
 
505
- return serde_yaml::Value::Mapping(mapping);
505
+ return yaml_serde::Value::Mapping(mapping);
506
506
  }
507
507
 
508
508
  if let Some(sequence) = node.descendants().find_map(BlockSeq::cast) {
509
- let values: Vec<serde_yaml::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
509
+ let values: Vec<yaml_serde::Value> = sequence.entries().map(|entry| node_to_yaml_value(entry.syntax())).collect();
510
510
 
511
- return serde_yaml::Value::Sequence(values);
511
+ return yaml_serde::Value::Sequence(values);
512
512
  }
513
513
 
514
514
  if let Some(block_scalar) = node.descendants().find(|child| child.kind() == SyntaxKind::BLOCK_SCALAR) {
@@ -521,35 +521,35 @@ pub(crate) fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
521
521
 
522
522
  let text = dedent_block_scalar(&text);
523
523
 
524
- return serde_yaml::Value::String(text);
524
+ return yaml_serde::Value::String(text);
525
525
  }
526
526
 
527
527
  if let Some(scalar) = extract_scalar(node) {
528
528
  use crate::syntax::{detect_yaml_type, is_yaml_truthy, YerbaValueType};
529
529
 
530
530
  return match detect_yaml_type(&scalar) {
531
- YerbaValueType::Null => serde_yaml::Value::Null,
532
- YerbaValueType::Boolean => serde_yaml::Value::Bool(is_yaml_truthy(&scalar.text)),
531
+ YerbaValueType::Null => yaml_serde::Value::Null,
532
+ YerbaValueType::Boolean => yaml_serde::Value::Bool(is_yaml_truthy(&scalar.text)),
533
533
 
534
534
  YerbaValueType::Integer => scalar
535
535
  .text
536
536
  .parse::<i64>()
537
- .map(|n| serde_yaml::Value::Number(serde_yaml::Number::from(n)))
538
- .unwrap_or(serde_yaml::Value::String(scalar.text)),
537
+ .map(|n| yaml_serde::Value::Number(yaml_serde::Number::from(n)))
538
+ .unwrap_or(yaml_serde::Value::String(scalar.text)),
539
539
 
540
540
  YerbaValueType::Float => scalar
541
541
  .text
542
542
  .parse::<f64>()
543
- .map(|n| serde_yaml::Value::Number(serde_yaml::Number::from(n)))
544
- .unwrap_or(serde_yaml::Value::String(scalar.text)),
543
+ .map(|n| yaml_serde::Value::Number(yaml_serde::Number::from(n)))
544
+ .unwrap_or(yaml_serde::Value::String(scalar.text)),
545
545
 
546
- YerbaValueType::String => serde_yaml::Value::String(scalar.text),
546
+ YerbaValueType::String => yaml_serde::Value::String(scalar.text),
547
547
  };
548
548
  }
549
549
 
550
550
  let text = node.text().to_string();
551
551
 
552
- serde_yaml::from_str(&text).unwrap_or(serde_yaml::Value::String(text))
552
+ yaml_serde::from_str(&text).unwrap_or(yaml_serde::Value::String(text))
553
553
  }
554
554
 
555
555
  pub(crate) fn parse_condition(condition: &str) -> Option<(String, &str, String)> {
@@ -577,10 +577,10 @@ impl Document {
577
577
  };
578
578
 
579
579
  let labels: Vec<String> = match self.get_value(&items_selector) {
580
- Some(serde_yaml::Value::Sequence(sequence)) => sequence
580
+ Some(yaml_serde::Value::Sequence(sequence)) => sequence
581
581
  .iter()
582
582
  .map(|value| match value {
583
- serde_yaml::Value::String(string) => string.clone(),
583
+ yaml_serde::Value::String(string) => string.clone(),
584
584
  _ => String::new(),
585
585
  })
586
586
  .collect(),
data/rust/src/json.rs CHANGED
@@ -1,11 +1,11 @@
1
1
  use crate::selector::{Selector, SelectorSegment};
2
2
 
3
- pub fn yaml_to_json(value: &serde_yaml::Value) -> serde_json::Value {
3
+ pub fn yaml_to_json(value: &yaml_serde::Value) -> serde_json::Value {
4
4
  match value {
5
- serde_yaml::Value::Null => serde_json::Value::Null,
6
- serde_yaml::Value::Bool(boolean) => serde_json::Value::Bool(*boolean),
5
+ yaml_serde::Value::Null => serde_json::Value::Null,
6
+ yaml_serde::Value::Bool(boolean) => serde_json::Value::Bool(*boolean),
7
7
 
8
- serde_yaml::Value::Number(number) => {
8
+ yaml_serde::Value::Number(number) => {
9
9
  if let Some(integer) = number.as_i64() {
10
10
  serde_json::Value::Number(integer.into())
11
11
  } else if let Some(float) = number.as_f64() {
@@ -15,16 +15,16 @@ pub fn yaml_to_json(value: &serde_yaml::Value) -> serde_json::Value {
15
15
  }
16
16
  }
17
17
 
18
- serde_yaml::Value::String(string) => serde_json::Value::String(string.clone()),
18
+ yaml_serde::Value::String(string) => serde_json::Value::String(string.clone()),
19
19
 
20
- serde_yaml::Value::Sequence(sequence) => serde_json::Value::Array(sequence.iter().map(yaml_to_json).collect()),
20
+ yaml_serde::Value::Sequence(sequence) => serde_json::Value::Array(sequence.iter().map(yaml_to_json).collect()),
21
21
 
22
- serde_yaml::Value::Mapping(mapping) => {
22
+ yaml_serde::Value::Mapping(mapping) => {
23
23
  let mut map = serde_json::Map::new();
24
24
 
25
25
  for (key, yaml_value) in mapping {
26
26
  let json_key = match key {
27
- serde_yaml::Value::String(string) => string.clone(),
27
+ yaml_serde::Value::String(string) => string.clone(),
28
28
  _ => format!("{:?}", key),
29
29
  };
30
30
 
@@ -34,19 +34,19 @@ pub fn yaml_to_json(value: &serde_yaml::Value) -> serde_json::Value {
34
34
  serde_json::Value::Object(map)
35
35
  }
36
36
 
37
- serde_yaml::Value::Tagged(tagged) => yaml_to_json(&tagged.value),
37
+ yaml_serde::Value::Tagged(tagged) => yaml_to_json(&tagged.value),
38
38
  }
39
39
  }
40
40
 
41
- pub fn resolve_select_field(value: &serde_yaml::Value, field: &str) -> serde_json::Value {
41
+ pub fn resolve_select_field(value: &yaml_serde::Value, field: &str) -> serde_json::Value {
42
42
  let parsed = Selector::parse(field);
43
43
  let segments = parsed.segments();
44
44
 
45
45
  if segments.len() == 1 {
46
46
  if let SelectorSegment::Key(key) = &segments[0] {
47
- if let serde_yaml::Value::Mapping(map) = value {
47
+ if let yaml_serde::Value::Mapping(map) = value {
48
48
  for (map_key, yaml_value) in map {
49
- if let serde_yaml::Value::String(key_string) = map_key {
49
+ if let yaml_serde::Value::String(key_string) = map_key {
50
50
  if key_string == key {
51
51
  return yaml_to_json(yaml_value);
52
52
  }
@@ -66,13 +66,13 @@ pub fn resolve_select_field(value: &serde_yaml::Value, field: &str) -> serde_jso
66
66
  for current in &current_values {
67
67
  match segment {
68
68
  SelectorSegment::AllItems => {
69
- if let serde_yaml::Value::Sequence(sequence) = current {
69
+ if let yaml_serde::Value::Sequence(sequence) = current {
70
70
  next_values.extend(sequence.iter().cloned());
71
71
  }
72
72
  }
73
73
 
74
74
  SelectorSegment::Index(index) => {
75
- if let serde_yaml::Value::Sequence(sequence) = current {
75
+ if let yaml_serde::Value::Sequence(sequence) = current {
76
76
  if let Some(item) = sequence.get(*index) {
77
77
  next_values.push(item.clone());
78
78
  }
@@ -80,9 +80,9 @@ pub fn resolve_select_field(value: &serde_yaml::Value, field: &str) -> serde_jso
80
80
  }
81
81
 
82
82
  SelectorSegment::Key(key) => {
83
- if let serde_yaml::Value::Mapping(map) = current {
83
+ if let yaml_serde::Value::Mapping(map) = current {
84
84
  for (map_key, yaml_value) in map {
85
- if let serde_yaml::Value::String(key_string) = map_key {
85
+ if let yaml_serde::Value::String(key_string) = map_key {
86
86
  if key_string == key {
87
87
  next_values.push(yaml_value.clone());
88
88
  }
data/rust/src/lib.rs CHANGED
@@ -88,10 +88,10 @@ pub fn glob_find(pattern: &str, selector: &str, condition: Option<&str>, select:
88
88
  }
89
89
  }
90
90
  None => {
91
- if let serde_yaml::Value::Mapping(map) = value {
91
+ if let yaml_serde::Value::Mapping(map) = value {
92
92
  for (key, yaml_value) in map {
93
93
  let json_key = match key {
94
- serde_yaml::Value::String(string) => string.clone(),
94
+ yaml_serde::Value::String(string) => string.clone(),
95
95
  _ => format!("{:?}", key),
96
96
  };
97
97
 
data/rust/src/selector.rs CHANGED
@@ -171,6 +171,22 @@ impl Selector {
171
171
 
172
172
  result
173
173
  }
174
+
175
+ pub fn parent_path(&self) -> String {
176
+ let segments = self.segments();
177
+
178
+ if segments.len() <= 1 {
179
+ return String::new();
180
+ }
181
+
182
+ let parent_segments = &segments[..segments.len() - 1];
183
+ let parent = match self {
184
+ Selector::Relative(_) => Selector::Relative(parent_segments.to_vec()),
185
+ Selector::Absolute(_) => Selector::Absolute(parent_segments.to_vec()),
186
+ };
187
+
188
+ parent.to_selector_string()
189
+ }
174
190
  }
175
191
 
176
192
  fn parse_segments(input: &str) -> Vec<SelectorSegment> {
@@ -108,65 +108,65 @@ impl<'de> Deserialize<'de> for PipelineStep {
108
108
  where
109
109
  D: serde::Deserializer<'de>,
110
110
  {
111
- let mapping = serde_yaml::Mapping::deserialize(deserializer)?;
111
+ let mapping = yaml_serde::Mapping::deserialize(deserializer)?;
112
112
 
113
- if let Some(value) = mapping.get(serde_yaml::Value::String("sort_keys".to_string())) {
114
- let config: SortKeysConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
113
+ if let Some(value) = mapping.get(yaml_serde::Value::String("sort_keys".to_string())) {
114
+ let config: SortKeysConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
115
115
  return Ok(PipelineStep::SortKeys(config));
116
116
  }
117
117
 
118
- if let Some(value) = mapping.get(serde_yaml::Value::String("quote_style".to_string())) {
119
- let config: QuoteStyleConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
118
+ if let Some(value) = mapping.get(yaml_serde::Value::String("quote_style".to_string())) {
119
+ let config: QuoteStyleConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
120
120
  return Ok(PipelineStep::QuoteStyle(config));
121
121
  }
122
122
 
123
- if let Some(value) = mapping.get(serde_yaml::Value::String("set".to_string())) {
124
- let config: SetConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
123
+ if let Some(value) = mapping.get(yaml_serde::Value::String("set".to_string())) {
124
+ let config: SetConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
125
125
  return Ok(PipelineStep::Set(config));
126
126
  }
127
127
 
128
- if let Some(value) = mapping.get(serde_yaml::Value::String("insert".to_string())) {
129
- let config: InsertConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
128
+ if let Some(value) = mapping.get(yaml_serde::Value::String("insert".to_string())) {
129
+ let config: InsertConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
130
130
  return Ok(PipelineStep::Insert(config));
131
131
  }
132
132
 
133
- if let Some(value) = mapping.get(serde_yaml::Value::String("delete".to_string())) {
134
- let config: DeleteConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
133
+ if let Some(value) = mapping.get(yaml_serde::Value::String("delete".to_string())) {
134
+ let config: DeleteConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
135
135
  return Ok(PipelineStep::Delete(config));
136
136
  }
137
137
 
138
- if let Some(value) = mapping.get(serde_yaml::Value::String("rename".to_string())) {
139
- let config: RenameConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
138
+ if let Some(value) = mapping.get(yaml_serde::Value::String("rename".to_string())) {
139
+ let config: RenameConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
140
140
  return Ok(PipelineStep::Rename(config));
141
141
  }
142
142
 
143
- if let Some(value) = mapping.get(serde_yaml::Value::String("remove".to_string())) {
144
- let config: RemoveConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
143
+ if let Some(value) = mapping.get(yaml_serde::Value::String("remove".to_string())) {
144
+ let config: RemoveConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
145
145
  return Ok(PipelineStep::Remove(config));
146
146
  }
147
147
 
148
- if let Some(value) = mapping.get(serde_yaml::Value::String("blank_lines".to_string())) {
149
- let config: BlankLinesConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
148
+ if let Some(value) = mapping.get(yaml_serde::Value::String("blank_lines".to_string())) {
149
+ let config: BlankLinesConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
150
150
  return Ok(PipelineStep::BlankLines(config));
151
151
  }
152
152
 
153
- if let Some(value) = mapping.get(serde_yaml::Value::String("directives".to_string())) {
154
- let config: DirectivesConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
153
+ if let Some(value) = mapping.get(yaml_serde::Value::String("directives".to_string())) {
154
+ let config: DirectivesConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
155
155
  return Ok(PipelineStep::Directives(config));
156
156
  }
157
157
 
158
- if let Some(value) = mapping.get(serde_yaml::Value::String("sort".to_string())) {
159
- let config: SortConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
158
+ if let Some(value) = mapping.get(yaml_serde::Value::String("sort".to_string())) {
159
+ let config: SortConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
160
160
  return Ok(PipelineStep::Sort(config));
161
161
  }
162
162
 
163
- if let Some(value) = mapping.get(serde_yaml::Value::String("unique".to_string())) {
164
- let config: UniqueConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
163
+ if let Some(value) = mapping.get(yaml_serde::Value::String("unique".to_string())) {
164
+ let config: UniqueConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
165
165
  return Ok(PipelineStep::Unique(config));
166
166
  }
167
167
 
168
- if let Some(value) = mapping.get(serde_yaml::Value::String("schema".to_string())) {
169
- let config: SchemaConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
168
+ if let Some(value) = mapping.get(yaml_serde::Value::String("schema".to_string())) {
169
+ let config: SchemaConfig = yaml_serde::from_value(value.clone()).map_err(serde::de::Error::custom)?;
170
170
  return Ok(PipelineStep::Schema(config));
171
171
  }
172
172
 
@@ -229,7 +229,7 @@ pub struct RuleResult {
229
229
  impl Yerbafile {
230
230
  pub fn load(path: impl AsRef<Path>) -> Result<Self, YerbaError> {
231
231
  let content = fs::read_to_string(path.as_ref())?;
232
- let mut yerbafile: Yerbafile = serde_yaml::from_str(&content).map_err(|error| YerbaError::ParseError(format!("{}", error)))?;
232
+ let mut yerbafile: Yerbafile = yaml_serde::from_str(&content).map_err(|error| YerbaError::ParseError(format!("{}", error)))?;
233
233
  yerbafile.directory = path.as_ref().parent().map(|p| p.to_path_buf());
234
234
  Ok(yerbafile)
235
235
  }
@@ -311,50 +311,6 @@ impl Yerbafile {
311
311
 
312
312
  let file_strings: Vec<String> = files.iter().map(|path| path.to_string_lossy().to_string()).collect();
313
313
 
314
- let mut has_validation_error = false;
315
-
316
- for step in &rule.pipeline {
317
- if let PipelineStep::SortKeys(config) = step {
318
- let full_path = resolve_step_path(rule.path.as_deref(), config.path.as_deref());
319
- let key_order: Vec<&str> = config.order.iter().map(|key| key.as_str()).collect();
320
-
321
- let validation_results: Vec<RuleResult> = file_strings
322
- .par_iter()
323
- .filter_map(|file| {
324
- let document = match Document::parse_file(file) {
325
- Ok(document) => document,
326
- Err(error) => {
327
- return Some(RuleResult {
328
- file: file.clone(),
329
- changed: false,
330
- error: Some(error),
331
- });
332
- }
333
- };
334
-
335
- if let Err(error) = document.validate_sort_keys(&full_path, &key_order) {
336
- Some(RuleResult {
337
- file: file.clone(),
338
- changed: false,
339
- error: Some(error),
340
- })
341
- } else {
342
- None
343
- }
344
- })
345
- .collect();
346
-
347
- if !validation_results.is_empty() {
348
- has_validation_error = true;
349
- results.extend(validation_results);
350
- }
351
- }
352
- }
353
-
354
- if has_validation_error {
355
- continue;
356
- }
357
-
358
314
  let file_results: Vec<RuleResult> = file_strings.par_iter().map(|file| self.apply_pipeline_to_file(rule, file, write)).collect();
359
315
 
360
316
  results.extend(file_results);
@@ -474,6 +430,7 @@ fn execute_step(document: &mut Document, step: &PipelineStep, base_path: Option<
474
430
  let full_path = resolve_step_path(base_path, config.path.as_deref());
475
431
  let key_order: Vec<&str> = config.order.iter().map(|key| key.as_str()).collect();
476
432
 
433
+ document.validate_sort_keys(&full_path, &key_order)?;
477
434
  document.sort_keys(&full_path, &key_order)
478
435
  }
479
436
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yerba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: x86_64-linux-gnu
6
6
  authors:
7
7
  - Marco Roth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-12 00:00:00.000000000 Z
11
+ date: 2026-05-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A CLI tool for editing YAML while preserving structure, comments, and
14
14
  format.