yerba 0.2.2-arm-linux-gnu → 0.3.0-arm-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.
data/rust/src/document.rs CHANGED
@@ -53,7 +53,7 @@ impl SortField {
53
53
  }
54
54
  }
55
55
 
56
- #[derive(Debug)]
56
+ #[derive(Debug, Clone)]
57
57
  pub enum InsertPosition {
58
58
  At(usize),
59
59
  Last,
@@ -169,6 +169,18 @@ impl Document {
169
169
  .collect()
170
170
  }
171
171
 
172
+ pub fn selectors(&self) -> Vec<String> {
173
+ let Some(value) = self.get_value("") else {
174
+ return Vec::new();
175
+ };
176
+
177
+ let mut selectors = Vec::new();
178
+ collect_selectors(&value, "", &mut selectors);
179
+ selectors.sort();
180
+ selectors.dedup();
181
+ selectors
182
+ }
183
+
172
184
  fn evaluate_condition_on_node(&self, node: &SyntaxNode, condition: &str) -> bool {
173
185
  let condition = condition.trim();
174
186
 
@@ -354,17 +366,35 @@ impl Document {
354
366
  }
355
367
 
356
368
  let scalar_token =
357
- find_scalar_token(&current_node).ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
369
+ find_scalar_token(&current_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
358
370
 
359
371
  let new_text = format_scalar_value(value, scalar_token.kind());
360
372
 
361
373
  self.replace_token(&scalar_token, &new_text)
362
374
  }
363
375
 
376
+ pub fn set_all(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
377
+ let nodes = self.navigate_all(dot_path);
378
+
379
+ if nodes.is_empty() {
380
+ return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
381
+ }
382
+
383
+ for node in nodes.into_iter().rev() {
384
+ if let Some(scalar_token) = find_scalar_token(&node) {
385
+ let new_text = format_scalar_value(value, scalar_token.kind());
386
+
387
+ self.replace_token(&scalar_token, &new_text)?;
388
+ }
389
+ }
390
+
391
+ Ok(())
392
+ }
393
+
364
394
  pub fn set_scalar_style(&mut self, dot_path: &str, style: &QuoteStyle) -> Result<(), YerbaError> {
365
395
  let current_node = self.navigate(dot_path)?;
366
396
  let scalar_token =
367
- find_scalar_token(&current_node).ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
397
+ find_scalar_token(&current_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
368
398
 
369
399
  let current_kind = scalar_token.kind();
370
400
  let target_kind = style.to_syntax_kind();
@@ -406,7 +436,7 @@ impl Document {
406
436
  }
407
437
 
408
438
  let scalar_token =
409
- find_scalar_token(&current_node).ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
439
+ find_scalar_token(&current_node).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
410
440
 
411
441
  self.replace_token(&scalar_token, value)
412
442
  }
@@ -440,7 +470,7 @@ impl Document {
440
470
  let entries: Vec<_> = sequence.entries().collect();
441
471
 
442
472
  if entries.is_empty() {
443
- return Err(YerbaError::PathNotFound(dot_path.to_string()));
473
+ return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
444
474
  }
445
475
 
446
476
  let indent = entries
@@ -515,7 +545,7 @@ impl Document {
515
545
  .map(|text| text == target_value)
516
546
  .unwrap_or(false)
517
547
  })
518
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} item '{}'", dot_path, target_value)))?;
548
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", dot_path, target_value)))?;
519
549
 
520
550
  let target_range = target_entry.syntax().text_range();
521
551
  let replacement = format!("{}\n{}", new_item, indent);
@@ -534,7 +564,7 @@ impl Document {
534
564
  .map(|text| text == target_value)
535
565
  .unwrap_or(false)
536
566
  })
537
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} item '{}'", dot_path, target_value)))?;
567
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", dot_path, target_value)))?;
538
568
 
539
569
  let new_text = format!("\n{}{}", indent, new_item);
540
570
 
@@ -545,7 +575,7 @@ impl Document {
545
575
  let target_entry = entries
546
576
  .iter()
547
577
  .find(|entry| self.evaluate_condition_on_node(entry.syntax(), &condition))
548
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} condition '{}'", dot_path, condition)))?;
578
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} condition '{}'", dot_path, condition)))?;
549
579
 
550
580
  let target_range = target_entry.syntax().text_range();
551
581
  let replacement = format!("{}\n{}", new_item, indent);
@@ -558,7 +588,7 @@ impl Document {
558
588
  let target_entry = entries
559
589
  .iter()
560
590
  .find(|entry| self.evaluate_condition_on_node(entry.syntax(), &condition))
561
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} condition '{}'", dot_path, condition)))?;
591
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} condition '{}'", dot_path, condition)))?;
562
592
 
563
593
  let new_text = format!("\n{}{}", indent, new_item);
564
594
 
@@ -586,7 +616,7 @@ impl Document {
586
616
  let map = current_node
587
617
  .descendants()
588
618
  .find_map(BlockMap::cast)
589
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
619
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
590
620
 
591
621
  let entries: Vec<_> = map.entries().collect();
592
622
 
@@ -638,7 +668,7 @@ impl Document {
638
668
 
639
669
  InsertPosition::Before(target_key) => {
640
670
  let target_entry = find_entry_by_key(&map, &target_key)
641
- .ok_or_else(|| YerbaError::PathNotFound(format!("{}.{}", dot_path, target_key)))?;
671
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{}.{}", dot_path, target_key)))?;
642
672
 
643
673
  let target_range = target_entry.syntax().text_range();
644
674
  let replacement = format!("{}\n{}", new_entry_text, indent);
@@ -649,7 +679,7 @@ impl Document {
649
679
 
650
680
  InsertPosition::After(target_key) => {
651
681
  let target_entry = find_entry_by_key(&map, &target_key)
652
- .ok_or_else(|| YerbaError::PathNotFound(format!("{}.{}", dot_path, target_key)))?;
682
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{}.{}", dot_path, target_key)))?;
653
683
 
654
684
  let new_text = format!("\n{}{}", indent, new_entry_text);
655
685
 
@@ -711,17 +741,17 @@ impl Document {
711
741
  let map = parent_node
712
742
  .descendants()
713
743
  .find_map(BlockMap::cast)
714
- .ok_or_else(|| YerbaError::PathNotFound(source_path.to_string()))?;
744
+ .ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
715
745
 
716
746
  let entry =
717
- find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::PathNotFound(source_path.to_string()))?;
747
+ find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
718
748
 
719
749
  let key_node = entry
720
750
  .key()
721
- .ok_or_else(|| YerbaError::PathNotFound(source_path.to_string()))?;
751
+ .ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
722
752
 
723
753
  let key_token =
724
- find_scalar_token(key_node.syntax()).ok_or_else(|| YerbaError::PathNotFound(source_path.to_string()))?;
754
+ find_scalar_token(key_node.syntax()).ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
725
755
 
726
756
  let new_text = format_scalar_value(destination_key, key_token.kind());
727
757
 
@@ -729,7 +759,7 @@ impl Document {
729
759
  } else {
730
760
  let value = self
731
761
  .get(source_path)
732
- .ok_or_else(|| YerbaError::PathNotFound(source_path.to_string()))?;
762
+ .ok_or_else(|| YerbaError::SelectorNotFound(source_path.to_string()))?;
733
763
 
734
764
  self.delete(source_path)?;
735
765
  self.insert_into(destination_path, &value, InsertPosition::Last)
@@ -745,9 +775,9 @@ impl Document {
745
775
  let map = parent_node
746
776
  .descendants()
747
777
  .find_map(BlockMap::cast)
748
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
778
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
749
779
 
750
- let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
780
+ let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
751
781
 
752
782
  self.remove_node(entry.syntax())
753
783
  }
@@ -769,7 +799,7 @@ impl Document {
769
799
  .map(|text| text == value)
770
800
  .unwrap_or(false)
771
801
  })
772
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} item '{}'", dot_path, value)))?;
802
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", dot_path, value)))?;
773
803
 
774
804
  self.remove_node(target_entry.syntax())
775
805
  }
@@ -820,7 +850,7 @@ impl Document {
820
850
  let map = current_node
821
851
  .descendants()
822
852
  .find_map(BlockMap::cast)
823
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
853
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
824
854
 
825
855
  let entries: Vec<_> = map.entries().collect();
826
856
 
@@ -833,7 +863,7 @@ impl Document {
833
863
  let map = current_node
834
864
  .descendants()
835
865
  .find_map(BlockMap::cast)
836
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
866
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
837
867
 
838
868
  if let Ok(index) = reference.parse::<usize>() {
839
869
  let length = map.entries().count();
@@ -856,7 +886,7 @@ impl Document {
856
886
  .unwrap_or(false)
857
887
  })
858
888
  .map(|(index, _entry)| index)
859
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} key '{}'", dot_path, reference)))
889
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} key '{}'", dot_path, reference)))
860
890
  }
861
891
 
862
892
  pub fn resolve_sequence_index(&self, dot_path: &str, reference: &str) -> Result<usize, YerbaError> {
@@ -883,7 +913,7 @@ impl Document {
883
913
  .enumerate()
884
914
  .find(|(_index, entry)| self.evaluate_condition_on_node(entry.syntax(), reference))
885
915
  .map(|(index, _entry)| index)
886
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} condition '{}'", dot_path, reference)));
916
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} condition '{}'", dot_path, reference)));
887
917
  }
888
918
 
889
919
  sequence
@@ -897,7 +927,7 @@ impl Document {
897
927
  .unwrap_or(false)
898
928
  })
899
929
  .map(|(index, _entry)| index)
900
- .ok_or_else(|| YerbaError::PathNotFound(format!("{} item '{}'", dot_path, reference)))
930
+ .ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", dot_path, reference)))
901
931
  }
902
932
 
903
933
  pub fn validate_sort_keys(&self, dot_path: &str, key_order: &[&str]) -> Result<(), YerbaError> {
@@ -916,7 +946,7 @@ impl Document {
916
946
  let map = current_node
917
947
  .descendants()
918
948
  .find_map(BlockMap::cast)
919
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
949
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
920
950
 
921
951
  let unknown_keys: Vec<String> = map
922
952
  .entries()
@@ -947,7 +977,7 @@ impl Document {
947
977
  let map = current_node
948
978
  .descendants()
949
979
  .find_map(BlockMap::cast)
950
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
980
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
951
981
 
952
982
  let entries: Vec<_> = map.entries().collect();
953
983
 
@@ -1000,7 +1030,7 @@ impl Document {
1000
1030
  .unwrap_or_default();
1001
1031
 
1002
1032
  let sorted_groups: Vec<EntryGroup> = keyed.into_iter().map(|(_, group)| group).collect();
1003
- let map_text = rebuild_from_groups(&sorted_groups, &indent);
1033
+ let map_text = rebuild_from_groups(&sorted_groups, &indent, false);
1004
1034
 
1005
1035
  self.apply_edit(range, &map_text)
1006
1036
  }
@@ -1076,7 +1106,7 @@ impl Document {
1076
1106
  .unwrap_or_default();
1077
1107
 
1078
1108
  let sorted_groups: Vec<EntryGroup> = keyed.into_iter().map(|(_, group)| group).collect();
1079
- let map_text = rebuild_from_groups(&sorted_groups, &indent);
1109
+ let map_text = rebuild_from_groups(&sorted_groups, &indent, false);
1080
1110
  edits.push((group_range, map_text));
1081
1111
  }
1082
1112
 
@@ -1226,7 +1256,7 @@ impl Document {
1226
1256
  .unwrap_or_default();
1227
1257
 
1228
1258
  let sorted_groups: Vec<EntryGroup> = sortable.into_iter().map(|(_, group)| group).collect();
1229
- let sequence_text = rebuild_from_groups(&sorted_groups, &indent);
1259
+ let sequence_text = rebuild_from_groups(&sorted_groups, &indent, true);
1230
1260
 
1231
1261
  self.apply_edit(range, &sequence_text)
1232
1262
  }
@@ -1334,7 +1364,7 @@ impl Document {
1334
1364
  .unwrap_or_default();
1335
1365
 
1336
1366
  let sorted_groups: Vec<EntryGroup> = sortable.into_iter().map(|(_, group)| group).collect();
1337
- let sequence_text = rebuild_from_groups(&sorted_groups, &indent);
1367
+ let sequence_text = rebuild_from_groups(&sorted_groups, &indent, true);
1338
1368
  edits.push((group_range, sequence_text));
1339
1369
  }
1340
1370
  }
@@ -1664,12 +1694,12 @@ impl Document {
1664
1694
  Self::validate_path(dot_path)?;
1665
1695
 
1666
1696
  if dot_path.is_empty() {
1667
- let root = Root::cast(self.root.clone()).ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
1697
+ let root = Root::cast(self.root.clone()).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
1668
1698
 
1669
1699
  let document = root
1670
1700
  .documents()
1671
1701
  .next()
1672
- .ok_or_else(|| YerbaError::PathNotFound(dot_path.to_string()))?;
1702
+ .ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
1673
1703
 
1674
1704
  return Ok(document.syntax().clone());
1675
1705
  }
@@ -1677,13 +1707,9 @@ impl Document {
1677
1707
  let nodes = self.navigate_all(dot_path);
1678
1708
 
1679
1709
  match nodes.len() {
1680
- 0 => Err(YerbaError::PathNotFound(dot_path.to_string())),
1710
+ 0 => Err(YerbaError::SelectorNotFound(dot_path.to_string())),
1681
1711
  1 => Ok(nodes.into_iter().next().unwrap()),
1682
- _ => Err(YerbaError::PathNotFound(format!(
1683
- "{} (matched {} nodes, expected 1)",
1684
- dot_path,
1685
- nodes.len()
1686
- ))),
1712
+ _ => Err(YerbaError::AmbiguousSelector(dot_path.to_string(), nodes.len())),
1687
1713
  }
1688
1714
  }
1689
1715
 
@@ -1844,7 +1870,7 @@ impl Document {
1844
1870
  .map(|entry| preceding_whitespace_indent(entry.syntax()))
1845
1871
  .unwrap_or_default();
1846
1872
 
1847
- let text = rebuild_from_groups(&reordered, &indent);
1873
+ let text = rebuild_from_groups(&reordered, &indent, true);
1848
1874
 
1849
1875
  self.apply_edit(range, &text)
1850
1876
  }
@@ -1871,6 +1897,36 @@ impl std::fmt::Display for Document {
1871
1897
  }
1872
1898
  }
1873
1899
 
1900
+ pub fn collect_selectors(value: &serde_yaml::Value, prefix: &str, selectors: &mut Vec<String>) {
1901
+ match value {
1902
+ serde_yaml::Value::Mapping(map) => {
1903
+ for (key, child) in map {
1904
+ if let serde_yaml::Value::String(key_string) = key {
1905
+ let selector = if prefix.is_empty() {
1906
+ key_string.clone()
1907
+ } else {
1908
+ format!("{}.{}", prefix, key_string)
1909
+ };
1910
+
1911
+ selectors.push(selector.clone());
1912
+ collect_selectors(child, &selector, selectors);
1913
+ }
1914
+ }
1915
+ }
1916
+
1917
+ serde_yaml::Value::Sequence(sequence) => {
1918
+ let bracket_prefix = format!("{}[]", prefix);
1919
+ selectors.push(bracket_prefix.clone());
1920
+
1921
+ for item in sequence {
1922
+ collect_selectors(item, &bracket_prefix, selectors);
1923
+ }
1924
+ }
1925
+
1926
+ _ => {}
1927
+ }
1928
+ }
1929
+
1874
1930
  pub fn node_to_yaml_value(node: &SyntaxNode) -> serde_yaml::Value {
1875
1931
  if let Some(sequence) = node.descendants().find_map(BlockSeq::cast) {
1876
1932
  let map_position = node
@@ -2178,8 +2234,7 @@ fn collect_preceding_sibling_comments(parent: &SyntaxNode) -> (String, Option<ro
2178
2234
  Some(parent)
2179
2235
  if parent.kind() == SyntaxKind::BLOCK
2180
2236
  || parent.kind() == SyntaxKind::DOCUMENT
2181
- || parent.kind() == SyntaxKind::BLOCK_MAP_VALUE
2182
- || parent.kind() == SyntaxKind::BLOCK_SEQ_ENTRY =>
2237
+ || parent.kind() == SyntaxKind::BLOCK_MAP_VALUE =>
2183
2238
  {
2184
2239
  node = parent
2185
2240
  }
@@ -2214,12 +2269,16 @@ fn collect_groups_with_range(parent: &SyntaxNode) -> (Vec<EntryGroup>, TextRange
2214
2269
  (groups, range)
2215
2270
  }
2216
2271
 
2217
- fn rebuild_from_groups(groups: &[EntryGroup], indent: &str) -> String {
2218
- let default_separator = groups
2219
- .iter()
2220
- .find(|group| !group.separator.is_empty())
2221
- .map(|group| group.separator.clone())
2222
- .unwrap_or_else(|| "\n".to_string());
2272
+ fn rebuild_from_groups(groups: &[EntryGroup], indent: &str, preserve_separators: bool) -> String {
2273
+ let default_separator = if preserve_separators {
2274
+ groups
2275
+ .iter()
2276
+ .find(|group| !group.separator.is_empty())
2277
+ .map(|group| group.separator.clone())
2278
+ .unwrap_or_else(|| "\n".to_string())
2279
+ } else {
2280
+ "\n".to_string()
2281
+ };
2223
2282
 
2224
2283
  groups
2225
2284
  .iter()
@@ -2227,10 +2286,18 @@ fn rebuild_from_groups(groups: &[EntryGroup], indent: &str) -> String {
2227
2286
  .map(|(index, group)| {
2228
2287
  if index == 0 {
2229
2288
  group.full_text()
2230
- } else if group.preceding.is_empty() {
2231
- format!("{}{}{}", default_separator, indent, group.body)
2232
2289
  } else {
2233
- format!("{}{}\n{}{}", default_separator, group.preceding, indent, group.body)
2290
+ let separator = if preserve_separators && !group.separator.is_empty() {
2291
+ &group.separator
2292
+ } else {
2293
+ &default_separator
2294
+ };
2295
+
2296
+ if group.preceding.is_empty() {
2297
+ format!("{}{}{}", separator, indent, group.body)
2298
+ } else {
2299
+ format!("{}{}\n{}{}", separator, group.preceding, indent, group.body)
2300
+ }
2234
2301
  }
2235
2302
  })
2236
2303
  .collect()
data/rust/src/error.rs CHANGED
@@ -2,7 +2,8 @@
2
2
  pub enum YerbaError {
3
3
  ParseError(String),
4
4
  IoError(std::io::Error),
5
- PathNotFound(String),
5
+ SelectorNotFound(String),
6
+ AmbiguousSelector(String, usize),
6
7
  NotASequence(String),
7
8
  IndexOutOfBounds(usize, usize),
8
9
  UnknownKeys(Vec<String>),
@@ -13,7 +14,16 @@ impl std::fmt::Display for YerbaError {
13
14
  match self {
14
15
  YerbaError::ParseError(msg) => write!(f, "parse error: {}", msg),
15
16
  YerbaError::IoError(err) => write!(f, "io error: {}", err),
16
- YerbaError::PathNotFound(path) => write!(f, "path not found: {}", path),
17
+ YerbaError::SelectorNotFound(selector) => write!(f, "selector not found: {}", selector),
18
+
19
+ YerbaError::AmbiguousSelector(selector, count) => {
20
+ write!(
21
+ f,
22
+ "selector \"{}\" matched {} nodes (expected 1). Use --all to update all matches",
23
+ selector, count
24
+ )
25
+ }
26
+
17
27
  YerbaError::NotASequence(path) => write!(f, "not a sequence: {}", path),
18
28
 
19
29
  YerbaError::IndexOutOfBounds(index, length) => {
data/rust/src/ffi.rs CHANGED
@@ -501,14 +501,19 @@ pub unsafe extern "C" fn yerba_document_set(
501
501
  path: *const c_char,
502
502
  value: *const c_char,
503
503
  value_type: YerbaValueType,
504
+ all: bool,
504
505
  ) -> YerbaResult {
505
506
  let document = &mut *document;
506
507
  let path_string = CStr::from_ptr(path).to_str().unwrap_or("");
507
508
  let value_string = CStr::from_ptr(value).to_str().unwrap_or("");
508
509
 
509
- let result = match value_type {
510
- YerbaValueType::String => document.set(path_string, value_string),
511
- _ => document.set_plain(path_string, value_string),
510
+ let result = if all {
511
+ document.set_all(path_string, value_string)
512
+ } else {
513
+ match value_type {
514
+ YerbaValueType::String => document.set(path_string, value_string),
515
+ _ => document.set_plain(path_string, value_string),
516
+ }
512
517
  };
513
518
 
514
519
  match result {
data/rust/src/lib.rs CHANGED
@@ -1,3 +1,4 @@
1
+ pub mod didyoumean;
1
2
  mod document;
2
3
  mod error;
3
4
  pub mod ffi;
@@ -8,7 +9,7 @@ mod syntax;
8
9
  mod yaml_writer;
9
10
  pub mod yerbafile;
10
11
 
11
- pub use document::{Document, InsertPosition, SortField};
12
+ pub use document::{collect_selectors, Document, InsertPosition, SortField};
12
13
  pub use error::YerbaError;
13
14
  pub use quote_style::QuoteStyle;
14
15
  pub use selector::Selector;
data/rust/src/main.rs CHANGED
@@ -45,6 +45,8 @@ static HELP: LazyLock<String> = LazyLock::new(|| {
45
45
  yerba move videos.yml "" ".id == talk-2" --after ".id == talk-1"
46
46
  yerba sort-keys config.yml "database" "id,host,port,name"
47
47
  yerba quote-style "data/**/*.yml" --values double
48
+ yerba sort videos.yml "[]" --by ".id" --order "talk-3,talk-1,talk-2"
49
+ yerba selectors videos.yml
48
50
  "#})
49
51
  });
50
52
 
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.2.2
4
+ version: 0.3.0
5
5
  platform: arm-linux-gnu
6
6
  authors:
7
7
  - Marco Roth
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-03 00:00:00.000000000 Z
11
+ date: 2026-05-04 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.
@@ -58,10 +58,12 @@ files:
58
58
  - rust/src/commands/quote_style.rs
59
59
  - rust/src/commands/remove.rs
60
60
  - rust/src/commands/rename.rs
61
+ - rust/src/commands/selectors.rs
61
62
  - rust/src/commands/set.rs
62
63
  - rust/src/commands/sort.rs
63
64
  - rust/src/commands/sort_keys.rs
64
65
  - rust/src/commands/version.rs
66
+ - rust/src/didyoumean.rs
65
67
  - rust/src/document.rs
66
68
  - rust/src/error.rs
67
69
  - rust/src/ffi.rs