yerba 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +492 -15
  3. data/ext/yerba/extconf.rb +87 -30
  4. data/ext/yerba/include/yerba.h +168 -0
  5. data/ext/yerba/yerba.c +752 -0
  6. data/lib/yerba/collection.rb +31 -0
  7. data/lib/yerba/document.rb +59 -0
  8. data/lib/yerba/formatting.rb +18 -0
  9. data/lib/yerba/location.rb +5 -0
  10. data/lib/yerba/map.rb +166 -0
  11. data/lib/yerba/scalar.rb +85 -0
  12. data/lib/yerba/sequence.rb +182 -0
  13. data/lib/yerba/version.rb +1 -1
  14. data/lib/yerba.rb +30 -4
  15. data/rust/Cargo.lock +378 -2
  16. data/rust/Cargo.toml +5 -1
  17. data/rust/build.rs +11 -0
  18. data/rust/cbindgen.toml +27 -0
  19. data/rust/src/commands/apply.rs +5 -0
  20. data/rust/src/commands/blank_lines.rs +58 -0
  21. data/rust/src/commands/check.rs +5 -0
  22. data/rust/src/commands/delete.rs +35 -0
  23. data/rust/src/commands/get.rs +194 -0
  24. data/rust/src/commands/init.rs +89 -0
  25. data/rust/src/commands/insert.rs +106 -0
  26. data/rust/src/commands/mate.rs +55 -0
  27. data/rust/src/commands/mod.rs +349 -0
  28. data/rust/src/commands/move_item.rs +54 -0
  29. data/rust/src/commands/move_key.rs +87 -0
  30. data/rust/src/commands/quote_style.rs +62 -0
  31. data/rust/src/commands/remove.rs +35 -0
  32. data/rust/src/commands/rename.rs +37 -0
  33. data/rust/src/commands/set.rs +59 -0
  34. data/rust/src/commands/sort.rs +52 -0
  35. data/rust/src/commands/sort_keys.rs +62 -0
  36. data/rust/src/commands/version.rs +8 -0
  37. data/rust/src/document.rs +764 -333
  38. data/rust/src/error.rs +0 -5
  39. data/rust/src/ffi.rs +991 -0
  40. data/rust/src/json.rs +49 -90
  41. data/rust/src/lib.rs +9 -2
  42. data/rust/src/main.rs +55 -843
  43. data/rust/src/selector.rs +241 -0
  44. data/rust/src/syntax.rs +97 -21
  45. data/rust/src/yaml_writer.rs +89 -0
  46. data/rust/src/yerbafile.rs +11 -126
  47. data/yerba.gemspec +4 -0
  48. metadata +33 -1
@@ -0,0 +1,52 @@
1
+ use std::sync::LazyLock;
2
+
3
+ use indoc::indoc;
4
+
5
+ use super::colorize_examples;
6
+ use super::{output, parse_file, resolve_files};
7
+
8
+ static EXAMPLES: LazyLock<String> = LazyLock::new(|| {
9
+ colorize_examples(indoc! {r#"
10
+ yerba sort config.yml "tags"
11
+ yerba sort videos.yml --by "title"
12
+ yerba sort videos.yml --by "date:desc,title"
13
+ yerba sort videos.yml "[].speakers"
14
+ yerba sort videos.yml "[].speakers" --by "name"
15
+ yerba sort videos.yml --by "kind,date:desc,title" --dry-run
16
+ "#})
17
+ });
18
+
19
+ #[derive(clap::Args)]
20
+ #[command(
21
+ about = "Sort items in a sequence by field(s)",
22
+ arg_required_else_help = true,
23
+ after_help = EXAMPLES.as_str()
24
+ )]
25
+ pub struct Args {
26
+ file: String,
27
+ /// Selector (optional — omit for root-level sequence)
28
+ selector: Option<String>,
29
+ /// Comma-separated sort fields, optionally with :desc (e.g. "date:desc,title")
30
+ #[arg(long)]
31
+ by: Option<String>,
32
+ /// Case-sensitive sort (default: case-insensitive)
33
+ #[arg(long)]
34
+ case_sensitive: bool,
35
+ #[arg(long)]
36
+ dry_run: bool,
37
+ }
38
+
39
+ impl Args {
40
+ pub fn run(self) {
41
+ let selector = self.selector.as_deref().unwrap_or("");
42
+ let sort_fields = self.by.as_deref().map(yerba::SortField::parse_list).unwrap_or_default();
43
+
44
+ for resolved_file in resolve_files(&self.file) {
45
+ let mut document = parse_file(&resolved_file);
46
+
47
+ if document.sort_items(selector, &sort_fields, self.case_sensitive).is_ok() {
48
+ output(&resolved_file, &document, self.dry_run);
49
+ }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,62 @@
1
+ use std::process;
2
+ use std::sync::LazyLock;
3
+
4
+ use indoc::indoc;
5
+
6
+ use super::colorize_examples;
7
+ use super::{output, parse_file, resolve_files};
8
+
9
+ static EXAMPLES: LazyLock<String> = LazyLock::new(|| {
10
+ colorize_examples(indoc! {r#"
11
+ yerba sort-keys config.yml "database" "host,port,name,pool"
12
+ yerba sort-keys "data/**/event.yml" "" "id,title,kind,location"
13
+ yerba sort-keys "data/**/videos.yml" "[]" "id,title,speakers"
14
+ yerba sort-keys config.yml "database" "host,port" --dry-run
15
+ "#})
16
+ });
17
+
18
+ #[derive(clap::Args)]
19
+ #[command(
20
+ about = "Sort keys in a map by a predefined order (aborts on unknown keys)",
21
+ arg_required_else_help = true,
22
+ after_help = EXAMPLES.as_str()
23
+ )]
24
+ pub struct Args {
25
+ file: String,
26
+ selector: String,
27
+ /// Comma-separated key order
28
+ order: String,
29
+ #[arg(long)]
30
+ dry_run: bool,
31
+ }
32
+
33
+ impl Args {
34
+ pub fn run(self) {
35
+ let key_order: Vec<&str> = self.order.split(',').collect();
36
+ let files = resolve_files(&self.file);
37
+
38
+ let mut has_errors = false;
39
+
40
+ for resolved_file in &files {
41
+ let document = parse_file(resolved_file);
42
+
43
+ if let Err(error) = document.validate_sort_keys(&self.selector, &key_order) {
44
+ use super::color::*;
45
+ eprintln!("{RED}Error in {}{RESET}: {}", resolved_file, error);
46
+ has_errors = true;
47
+ }
48
+ }
49
+
50
+ if has_errors {
51
+ process::exit(1);
52
+ }
53
+
54
+ for resolved_file in &files {
55
+ let mut document = parse_file(resolved_file);
56
+
57
+ if document.sort_keys(&self.selector, &key_order).is_ok() {
58
+ output(resolved_file, &document, self.dry_run);
59
+ }
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,8 @@
1
+ use super::color::*;
2
+
3
+ pub fn run() {
4
+ println!("🧉 {BOLD}yerba{RESET} {DIM}v{}{RESET}", yerba::version());
5
+ println!(
6
+ " {BOLD}Y{RESET}{DIM}AML{RESET} {BOLD}E{RESET}{DIM}diting and{RESET} {BOLD}R{RESET}{DIM}efactoring with{RESET} {BOLD}B{RESET}{DIM}etter{RESET} {BOLD}A{RESET}{DIM}ccuracy{RESET}"
7
+ );
8
+ }