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
@@ -1,6 +1,5 @@
1
1
  use rayon::prelude::*;
2
2
  use serde::Deserialize;
3
- use std::collections::HashMap;
4
3
  use std::fs;
5
4
  use std::path::{Path, PathBuf};
6
5
 
@@ -22,7 +21,6 @@ pub struct Rule {
22
21
 
23
22
  #[derive(Debug, Clone)]
24
23
  pub enum PipelineStep {
25
- Get(GetConfig),
26
24
  SortKeys(SortKeysConfig),
27
25
  QuoteStyle(QuoteStyleConfig),
28
26
  Set(SetConfig),
@@ -51,21 +49,6 @@ pub struct BlankLinesConfig {
51
49
  pub count: usize,
52
50
  }
53
51
 
54
- #[derive(Debug, Clone, Deserialize)]
55
- pub struct GetConfig {
56
- pub path: String,
57
- #[serde(rename = "as")]
58
- pub as_name: String,
59
- #[serde(default)]
60
- pub file: Option<String>,
61
- }
62
-
63
- #[derive(Debug, Clone)]
64
- pub enum Variable {
65
- Single(String),
66
- List(Vec<String>),
67
- }
68
-
69
52
  #[derive(Debug, Clone, Deserialize)]
70
53
  pub struct RenameConfig {
71
54
  pub from: String,
@@ -89,11 +72,6 @@ impl<'de> Deserialize<'de> for PipelineStep {
89
72
  {
90
73
  let mapping = serde_yaml::Mapping::deserialize(deserializer)?;
91
74
 
92
- if let Some(value) = mapping.get(serde_yaml::Value::String("get".to_string())) {
93
- let config: GetConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
94
- return Ok(PipelineStep::Get(config));
95
- }
96
-
97
75
  if let Some(value) = mapping.get(serde_yaml::Value::String("sort_keys".to_string())) {
98
76
  let config: SortKeysConfig = serde_yaml::from_value(value.clone()).map_err(serde::de::Error::custom)?;
99
77
  return Ok(PipelineStep::SortKeys(config));
@@ -140,7 +118,7 @@ impl<'de> Deserialize<'de> for PipelineStep {
140
118
  }
141
119
 
142
120
  Err(serde::de::Error::custom(
143
- "unknown pipeline step: expected get, sort_keys, quote_style, set, insert, delete, rename, remove, blank_lines, or sort",
121
+ "unknown pipeline step: expected sort_keys, quote_style, set, insert, delete, rename, remove, blank_lines, or sort",
144
122
  ))
145
123
  }
146
124
  }
@@ -338,10 +316,9 @@ impl Yerbafile {
338
316
 
339
317
  let original = document.to_string();
340
318
  let base_path = rule.path.as_deref();
341
- let mut variables: HashMap<String, Variable> = HashMap::new();
342
319
 
343
320
  for step in &rule.pipeline {
344
- if let Err(error) = execute_step(&mut document, step, base_path, &mut variables) {
321
+ if let Err(error) = execute_step(&mut document, step, base_path) {
345
322
  return RuleResult {
346
323
  file: file.to_string(),
347
324
  changed: false,
@@ -371,46 +348,8 @@ impl Yerbafile {
371
348
  }
372
349
  }
373
350
 
374
- fn execute_step(
375
- document: &mut Document,
376
- step: &PipelineStep,
377
- base_path: Option<&str>,
378
- variables: &mut HashMap<String, Variable>,
379
- ) -> Result<(), YerbaError> {
351
+ fn execute_step(document: &mut Document, step: &PipelineStep, base_path: Option<&str>) -> Result<(), YerbaError> {
380
352
  match step {
381
- PipelineStep::Get(config) => {
382
- let full_path = resolve_step_path(base_path, Some(&config.path));
383
-
384
- if let Some(file_pattern) = &config.file {
385
- let mut all_values = Vec::new();
386
-
387
- let files =
388
- glob::glob(file_pattern).map_err(|error| YerbaError::ParseError(format!("invalid glob: {}", error)))?;
389
-
390
- for entry in files.flatten() {
391
- let external_document = Document::parse_file(&entry)?;
392
- all_values.extend(external_document.get_all(&config.path));
393
- }
394
-
395
- if all_values.len() == 1 && !config.path.contains('[') {
396
- variables.insert(config.as_name.clone(), Variable::Single(all_values.remove(0)));
397
- } else {
398
- variables.insert(config.as_name.clone(), Variable::List(all_values));
399
- }
400
- } else if config.path.contains('[') {
401
- let values = document.get_all(&full_path);
402
-
403
- variables.insert(config.as_name.clone(), Variable::List(values));
404
- } else {
405
- let value = document
406
- .get(&full_path)
407
- .ok_or_else(|| YerbaError::PathNotFound(full_path.clone()))?;
408
- variables.insert(config.as_name.clone(), Variable::Single(value));
409
- }
410
-
411
- Ok(())
412
- }
413
-
414
353
  PipelineStep::QuoteStyle(config) => {
415
354
  let dot_path = config.path.as_deref();
416
355
 
@@ -436,44 +375,39 @@ fn execute_step(
436
375
 
437
376
  PipelineStep::Set(config) => {
438
377
  let full_path = resolve_step_path(base_path, Some(&config.path));
439
- let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
440
378
 
441
379
  if let Some(condition) = &config.condition {
442
- let resolved_condition = resolve_template(condition, document, base_path, variables)?;
443
380
  let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
444
381
 
445
- if !document.evaluate_condition(parent_path, &resolved_condition) {
382
+ if !document.evaluate_condition(parent_path, condition) {
446
383
  return Ok(());
447
384
  }
448
385
  }
449
386
 
450
- document.set(&full_path, &resolved_value)
387
+ document.set(&full_path, &config.value)
451
388
  }
452
389
 
453
390
  PipelineStep::Insert(config) => {
454
391
  let full_path = resolve_step_path(base_path, Some(&config.path));
455
- let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
456
392
 
457
393
  if let Some(condition) = &config.condition {
458
- let resolved_condition = resolve_template(condition, document, base_path, variables)?;
459
394
  let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
460
395
 
461
- if !document.evaluate_condition(parent_path, &resolved_condition) {
396
+ if !document.evaluate_condition(parent_path, condition) {
462
397
  return Ok(());
463
398
  }
464
399
  }
465
400
 
466
- document.insert_into(&full_path, &resolved_value, crate::InsertPosition::Last)
401
+ document.insert_into(&full_path, &config.value, crate::InsertPosition::Last)
467
402
  }
468
403
 
469
404
  PipelineStep::Delete(config) => {
470
405
  let full_path = resolve_step_path(base_path, Some(&config.path));
471
406
 
472
407
  if let Some(condition) = &config.condition {
473
- let resolved_condition = resolve_template(condition, document, base_path, variables)?;
474
408
  let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
475
409
 
476
- if !document.evaluate_condition(parent_path, &resolved_condition) {
410
+ if !document.evaluate_condition(parent_path, condition) {
477
411
  return Ok(());
478
412
  }
479
413
  }
@@ -485,10 +419,9 @@ fn execute_step(
485
419
  let full_path = resolve_step_path(base_path, Some(&config.from));
486
420
 
487
421
  if let Some(condition) = &config.condition {
488
- let resolved_condition = resolve_template(condition, document, base_path, variables)?;
489
422
  let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
490
423
 
491
- if !document.evaluate_condition(parent_path, &resolved_condition) {
424
+ if !document.evaluate_condition(parent_path, condition) {
492
425
  return Ok(());
493
426
  }
494
427
  }
@@ -498,18 +431,16 @@ fn execute_step(
498
431
 
499
432
  PipelineStep::Remove(config) => {
500
433
  let full_path = resolve_step_path(base_path, Some(&config.path));
501
- let resolved_value = resolve_template(&config.value, document, base_path, variables)?;
502
434
 
503
435
  if let Some(condition) = &config.condition {
504
- let resolved_condition = resolve_template(condition, document, base_path, variables)?;
505
436
  let parent_path = full_path.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
506
437
 
507
- if !document.evaluate_condition(parent_path, &resolved_condition) {
438
+ if !document.evaluate_condition(parent_path, condition) {
508
439
  return Ok(());
509
440
  }
510
441
  }
511
442
 
512
- document.remove(&full_path, &resolved_value)
443
+ document.remove(&full_path, &config.value)
513
444
  }
514
445
 
515
446
  PipelineStep::BlankLines(config) => {
@@ -531,52 +462,6 @@ fn execute_step(
531
462
  }
532
463
  }
533
464
 
534
- pub fn resolve_template(
535
- template: &str,
536
- document: &Document,
537
- base_path: Option<&str>,
538
- variables: &HashMap<String, Variable>,
539
- ) -> Result<String, YerbaError> {
540
- if !template.contains("${") {
541
- return Ok(template.to_string());
542
- }
543
-
544
- let mut result = String::new();
545
- let mut rest = template;
546
-
547
- while let Some(start) = rest.find("${") {
548
- result.push_str(&rest[..start]);
549
-
550
- let after_dollar = &rest[start + 2..];
551
-
552
- let end = after_dollar
553
- .find('}')
554
- .ok_or_else(|| YerbaError::ParseError("unclosed ${ in template".to_string()))?;
555
-
556
- let reference = &after_dollar[..end];
557
-
558
- let resolved = if let Some(variable) = variables.get(reference) {
559
- match variable {
560
- Variable::Single(value) => value.clone(),
561
- Variable::List(values) => values.join(", "),
562
- }
563
- } else {
564
- let full_path = resolve_step_path(base_path, Some(reference));
565
-
566
- document
567
- .get(&full_path)
568
- .ok_or_else(|| YerbaError::ReferenceNotFound(reference.to_string()))?
569
- };
570
-
571
- result.push_str(&resolved);
572
- rest = &after_dollar[end + 1..];
573
- }
574
-
575
- result.push_str(rest);
576
-
577
- Ok(result)
578
- }
579
-
580
465
  fn resolve_step_path(base_path: Option<&str>, step_path: Option<&str>) -> String {
581
466
  let base = base_path.unwrap_or("");
582
467
  let step = step_path.unwrap_or("");
data/yerba.gemspec CHANGED
@@ -28,6 +28,10 @@ Gem::Specification.new do |spec|
28
28
  "sig/**/*.rbs",
29
29
  "exe/yerba",
30
30
  "ext/yerba/extconf.rb",
31
+ "ext/yerba/yerba.c",
32
+ "ext/yerba/include/**/*.h",
33
+ "rust/build.rs",
34
+ "rust/cbindgen.toml",
31
35
  "rust/Cargo.toml",
32
36
  "rust/Cargo.lock",
33
37
  "rust/src/**/*.rs",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yerba
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Roth
@@ -23,18 +23,50 @@ files:
23
23
  - README.md
24
24
  - exe/yerba
25
25
  - ext/yerba/extconf.rb
26
+ - ext/yerba/include/yerba.h
27
+ - ext/yerba/yerba.c
26
28
  - lib/yerba.rb
29
+ - lib/yerba/collection.rb
30
+ - lib/yerba/document.rb
31
+ - lib/yerba/formatting.rb
32
+ - lib/yerba/location.rb
33
+ - lib/yerba/map.rb
34
+ - lib/yerba/scalar.rb
35
+ - lib/yerba/sequence.rb
27
36
  - lib/yerba/version.rb
28
37
  - rust/Cargo.lock
29
38
  - rust/Cargo.toml
39
+ - rust/build.rs
40
+ - rust/cbindgen.toml
30
41
  - rust/rustfmt.toml
42
+ - rust/src/commands/apply.rs
43
+ - rust/src/commands/blank_lines.rs
44
+ - rust/src/commands/check.rs
45
+ - rust/src/commands/delete.rs
46
+ - rust/src/commands/get.rs
47
+ - rust/src/commands/init.rs
48
+ - rust/src/commands/insert.rs
49
+ - rust/src/commands/mate.rs
50
+ - rust/src/commands/mod.rs
51
+ - rust/src/commands/move_item.rs
52
+ - rust/src/commands/move_key.rs
53
+ - rust/src/commands/quote_style.rs
54
+ - rust/src/commands/remove.rs
55
+ - rust/src/commands/rename.rs
56
+ - rust/src/commands/set.rs
57
+ - rust/src/commands/sort.rs
58
+ - rust/src/commands/sort_keys.rs
59
+ - rust/src/commands/version.rs
31
60
  - rust/src/document.rs
32
61
  - rust/src/error.rs
62
+ - rust/src/ffi.rs
33
63
  - rust/src/json.rs
34
64
  - rust/src/lib.rs
35
65
  - rust/src/main.rs
36
66
  - rust/src/quote_style.rs
67
+ - rust/src/selector.rs
37
68
  - rust/src/syntax.rs
69
+ - rust/src/yaml_writer.rs
38
70
  - rust/src/yerbafile.rs
39
71
  - sig/yerba.rbs
40
72
  - yerba.gemspec