yerba 0.9.2-aarch64-linux-gnu → 0.10.1-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 +4 -4
- data/README.md +53 -17
- data/exe/aarch64-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +58 -35
- data/ext/yerba/yerba.c +281 -187
- data/lib/yerba/3.2/yerba.so +0 -0
- data/lib/yerba/3.3/yerba.so +0 -0
- data/lib/yerba/3.4/yerba.so +0 -0
- data/lib/yerba/4.0/yerba.so +0 -0
- data/lib/yerba/collection.rb +4 -4
- data/lib/yerba/document.rb +134 -0
- data/lib/yerba/formatting.rb +1 -0
- data/lib/yerba/location.rb +8 -1
- data/lib/yerba/map.rb +16 -6
- data/lib/yerba/node.rb +41 -0
- data/lib/yerba/query_result.rb +33 -10
- data/lib/yerba/scalar.rb +29 -0
- data/lib/yerba/selector.rb +3 -1
- data/lib/yerba/sequence.rb +38 -33
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/commands/get.rs +12 -12
- data/rust/src/commands/init.rs +8 -8
- data/rust/src/commands/insert.rs +4 -18
- data/rust/src/commands/location.rs +2 -0
- data/rust/src/commands/mod.rs +34 -6
- data/rust/src/commands/move_item.rs +1 -1
- data/rust/src/commands/move_key.rs +8 -8
- data/rust/src/commands/rename.rs +1 -1
- data/rust/src/commands/selectors.rs +1 -1
- data/rust/src/commands/set.rs +14 -6
- data/rust/src/commands/sort.rs +5 -1
- data/rust/src/document/condition.rs +25 -25
- data/rust/src/document/delete.rs +57 -43
- data/rust/src/document/get.rs +91 -82
- data/rust/src/document/insert.rs +77 -77
- data/rust/src/document/mod.rs +202 -76
- data/rust/src/document/nodes.rs +162 -0
- data/rust/src/document/schema.rs +8 -8
- data/rust/src/document/set.rs +49 -26
- data/rust/src/document/sort.rs +105 -60
- data/rust/src/document/style.rs +50 -49
- data/rust/src/document/unique.rs +5 -5
- data/rust/src/error.rs +8 -4
- data/rust/src/ffi.rs +234 -107
- data/rust/src/json.rs +62 -2
- data/rust/src/lib.rs +4 -2
- data/rust/src/main.rs +2 -1
- data/rust/src/selector.rs +48 -7
- data/rust/src/syntax.rs +449 -56
- data/rust/src/validation.rs +5 -3
- data/rust/src/yerbafile.rs +168 -94
- metadata +3 -2
data/rust/src/document/style.rs
CHANGED
|
@@ -49,10 +49,7 @@ impl Document {
|
|
|
49
49
|
if let Some(ref entry) = entry_node {
|
|
50
50
|
let entry_start: usize = entry.text_range().start().into();
|
|
51
51
|
let key_indent = column_at(&source, entry_start);
|
|
52
|
-
let
|
|
53
|
-
|
|
54
|
-
if let Some(colon_offset) = entry_text.find(':') {
|
|
55
|
-
let colon_position = entry_start + colon_offset;
|
|
52
|
+
if let Some(colon_position) = entry_colon_position(entry) {
|
|
56
53
|
let value_indent = key_indent + 2;
|
|
57
54
|
let block_text = crate::yaml_writer::yaml_value_to_block_text(&value, value_indent);
|
|
58
55
|
let replace_range = TextRange::new(rowan::TextSize::from((colon_position + 1) as u32), node.text_range().end());
|
|
@@ -212,11 +209,11 @@ impl Document {
|
|
|
212
209
|
self.apply_edits(edits)
|
|
213
210
|
}
|
|
214
211
|
|
|
215
|
-
pub fn enforce_collection_style(&mut self, style: &str,
|
|
216
|
-
let
|
|
212
|
+
pub fn enforce_collection_style(&mut self, style: &str, selector: Option<&str>) -> Result<(), YerbaError> {
|
|
213
|
+
let scope_selector = selector.unwrap_or("");
|
|
217
214
|
|
|
218
|
-
if
|
|
219
|
-
let concrete_selectors = self.resolve_selectors(
|
|
215
|
+
if scope_selector.contains("[]") {
|
|
216
|
+
let concrete_selectors = self.resolve_selectors(scope_selector);
|
|
220
217
|
|
|
221
218
|
for selector in concrete_selectors.iter().rev() {
|
|
222
219
|
self.enforce_collection_style(style, Some(selector))?;
|
|
@@ -246,18 +243,18 @@ impl Document {
|
|
|
246
243
|
}
|
|
247
244
|
}
|
|
248
245
|
|
|
249
|
-
let value = match self.get_value(
|
|
246
|
+
let value = match self.get_value(scope_selector) {
|
|
250
247
|
Some(value) => value,
|
|
251
248
|
None => return Ok(()),
|
|
252
249
|
};
|
|
253
250
|
|
|
254
251
|
let mut selectors = Vec::new();
|
|
255
252
|
|
|
256
|
-
if !
|
|
257
|
-
selectors.push(
|
|
253
|
+
if !scope_selector.is_empty() {
|
|
254
|
+
selectors.push(scope_selector.to_string());
|
|
258
255
|
}
|
|
259
256
|
|
|
260
|
-
collect_selectors(&value,
|
|
257
|
+
collect_selectors(&value, scope_selector, &mut selectors);
|
|
261
258
|
|
|
262
259
|
let mut collection_selectors: Vec<String> = selectors
|
|
263
260
|
.into_iter()
|
|
@@ -273,11 +270,11 @@ impl Document {
|
|
|
273
270
|
Ok(())
|
|
274
271
|
}
|
|
275
272
|
|
|
276
|
-
pub fn enforce_sequence_indent(&mut self, style: &str,
|
|
277
|
-
let
|
|
273
|
+
pub fn enforce_sequence_indent(&mut self, style: &str, selector: Option<&str>) -> Result<(), YerbaError> {
|
|
274
|
+
let scope_selector = selector.unwrap_or("");
|
|
278
275
|
|
|
279
|
-
if
|
|
280
|
-
let concrete_selectors = self.resolve_selectors(
|
|
276
|
+
if scope_selector.contains("[]") {
|
|
277
|
+
let concrete_selectors = self.resolve_selectors(scope_selector);
|
|
281
278
|
|
|
282
279
|
for selector in concrete_selectors.iter().rev() {
|
|
283
280
|
self.enforce_sequence_indent(style, Some(selector))?;
|
|
@@ -286,10 +283,10 @@ impl Document {
|
|
|
286
283
|
return Ok(());
|
|
287
284
|
}
|
|
288
285
|
|
|
289
|
-
let scope_node = if
|
|
286
|
+
let scope_node = if scope_selector.is_empty() {
|
|
290
287
|
self.root.clone()
|
|
291
288
|
} else {
|
|
292
|
-
match self.navigate(
|
|
289
|
+
match self.navigate(scope_selector) {
|
|
293
290
|
Ok(node) => node,
|
|
294
291
|
Err(_) => return Ok(()),
|
|
295
292
|
}
|
|
@@ -333,10 +330,10 @@ impl Document {
|
|
|
333
330
|
loop {
|
|
334
331
|
let source = self.source_text();
|
|
335
332
|
|
|
336
|
-
let scope_node = if
|
|
333
|
+
let scope_node = if scope_selector.is_empty() {
|
|
337
334
|
self.root.clone()
|
|
338
335
|
} else {
|
|
339
|
-
match self.navigate(
|
|
336
|
+
match self.navigate(scope_selector) {
|
|
340
337
|
Ok(node) => node,
|
|
341
338
|
Err(_) => return Ok(()),
|
|
342
339
|
}
|
|
@@ -437,10 +434,10 @@ impl Document {
|
|
|
437
434
|
}
|
|
438
435
|
}
|
|
439
436
|
|
|
440
|
-
pub fn set_sequence_indent(&mut self,
|
|
437
|
+
pub fn set_sequence_indent(&mut self, selector: &str, style: &str) -> Result<(), YerbaError> {
|
|
441
438
|
let current_style = self
|
|
442
|
-
.get_sequence_indent(
|
|
443
|
-
.ok_or_else(|| YerbaError::ParseError(format!("'{}' is not a block sequence",
|
|
439
|
+
.get_sequence_indent(selector)
|
|
440
|
+
.ok_or_else(|| YerbaError::ParseError(format!("'{}' is not a block sequence", selector)))?;
|
|
444
441
|
|
|
445
442
|
if current_style == style {
|
|
446
443
|
return Ok(());
|
|
@@ -453,7 +450,7 @@ impl Document {
|
|
|
453
450
|
)));
|
|
454
451
|
}
|
|
455
452
|
|
|
456
|
-
let current_node = self.navigate(
|
|
453
|
+
let current_node = self.navigate(selector)?;
|
|
457
454
|
let source = self.source_text();
|
|
458
455
|
|
|
459
456
|
let entry_node = current_node
|
|
@@ -510,16 +507,16 @@ impl Document {
|
|
|
510
507
|
self.apply_edit(replace_range, &reindented)
|
|
511
508
|
}
|
|
512
509
|
|
|
513
|
-
pub fn set_collection_style(&mut self,
|
|
510
|
+
pub fn set_collection_style(&mut self, selector: &str, style: &str) -> Result<(), YerbaError> {
|
|
514
511
|
let current_style = self
|
|
515
|
-
.get_collection_style(
|
|
516
|
-
.ok_or_else(|| YerbaError::ParseError(format!("'{}' is not a collection (sequence or map)",
|
|
512
|
+
.get_collection_style(selector)
|
|
513
|
+
.ok_or_else(|| YerbaError::ParseError(format!("'{}' is not a collection (sequence or map)", selector)))?;
|
|
517
514
|
|
|
518
515
|
if current_style == style {
|
|
519
516
|
return Ok(());
|
|
520
517
|
}
|
|
521
518
|
|
|
522
|
-
let current_node = self.navigate(
|
|
519
|
+
let current_node = self.navigate(selector)?;
|
|
523
520
|
let value = node_to_yaml_value(¤t_node);
|
|
524
521
|
|
|
525
522
|
match &value {
|
|
@@ -536,10 +533,7 @@ impl Document {
|
|
|
536
533
|
let entry_start: usize = entry.text_range().start().into();
|
|
537
534
|
let indent = column_at(&source, entry_start);
|
|
538
535
|
|
|
539
|
-
|
|
540
|
-
let colon_offset = entry_text.find(':').map(|offset| entry_start + offset);
|
|
541
|
-
|
|
542
|
-
(indent, colon_offset)
|
|
536
|
+
(indent, entry_colon_position(entry))
|
|
543
537
|
} else {
|
|
544
538
|
(0, None)
|
|
545
539
|
};
|
|
@@ -594,15 +588,15 @@ impl Document {
|
|
|
594
588
|
}
|
|
595
589
|
}
|
|
596
590
|
|
|
597
|
-
pub fn enforce_blank_lines(&mut self,
|
|
598
|
-
self.enforce_blank_lines_with(
|
|
591
|
+
pub fn enforce_blank_lines(&mut self, selector: &str, blank_lines: usize) -> Result<(), YerbaError> {
|
|
592
|
+
self.enforce_blank_lines_with(selector, blank_lines, &BlankLineOptions::default())
|
|
599
593
|
}
|
|
600
594
|
|
|
601
|
-
pub fn enforce_blank_lines_with(&mut self,
|
|
602
|
-
let nodes = if
|
|
603
|
-
self.navigate_all_compact(
|
|
595
|
+
pub fn enforce_blank_lines_with(&mut self, selector: &str, blank_lines: usize, options: &BlankLineOptions) -> Result<(), YerbaError> {
|
|
596
|
+
let nodes = if selector.contains('[') {
|
|
597
|
+
self.navigate_all_compact(selector)
|
|
604
598
|
} else {
|
|
605
|
-
vec![self.navigate(
|
|
599
|
+
vec![self.navigate(selector)?]
|
|
606
600
|
};
|
|
607
601
|
|
|
608
602
|
let mut edits: Vec<(TextRange, String)> = Vec::new();
|
|
@@ -666,7 +660,7 @@ impl Document {
|
|
|
666
660
|
.map(|element| {
|
|
667
661
|
let offset: usize = element.text_range().start().into();
|
|
668
662
|
|
|
669
|
-
(line_at(&source, offset), column_at(&source, offset)
|
|
663
|
+
(line_at(&source, offset), column_at(&source, offset))
|
|
670
664
|
})
|
|
671
665
|
.collect()
|
|
672
666
|
}
|
|
@@ -709,9 +703,9 @@ impl Document {
|
|
|
709
703
|
}
|
|
710
704
|
}
|
|
711
705
|
|
|
712
|
-
pub fn enforce_key_style(&mut self, style: &crate::KeyStyle,
|
|
713
|
-
let scope_ranges: Vec<TextRange> = match
|
|
714
|
-
Some(
|
|
706
|
+
pub fn enforce_key_style(&mut self, style: &crate::KeyStyle, selector: Option<&str>) -> Result<(), YerbaError> {
|
|
707
|
+
let scope_ranges: Vec<TextRange> = match selector {
|
|
708
|
+
Some(scope) if !scope.is_empty() => self.navigate_all_compact(scope).iter().map(|node| node.text_range()).collect(),
|
|
715
709
|
_ => vec![self.root.text_range()],
|
|
716
710
|
};
|
|
717
711
|
|
|
@@ -779,9 +773,9 @@ impl Document {
|
|
|
779
773
|
self.enforce_quotes_at(style, None)
|
|
780
774
|
}
|
|
781
775
|
|
|
782
|
-
pub fn decode_escapes(&mut self,
|
|
783
|
-
let scope_ranges: Vec<TextRange> = match
|
|
784
|
-
Some(
|
|
776
|
+
pub fn decode_escapes(&mut self, selector: Option<&str>) -> Result<usize, YerbaError> {
|
|
777
|
+
let scope_ranges: Vec<TextRange> = match selector {
|
|
778
|
+
Some(scope) if !scope.is_empty() => self.navigate_all_compact(scope).iter().map(|node| node.text_range()).collect(),
|
|
785
779
|
_ => vec![self.root.text_range()],
|
|
786
780
|
};
|
|
787
781
|
|
|
@@ -814,11 +808,11 @@ impl Document {
|
|
|
814
808
|
Ok(count)
|
|
815
809
|
}
|
|
816
810
|
|
|
817
|
-
pub fn enforce_quotes_at(&mut self, style: &QuoteStyle,
|
|
811
|
+
pub fn enforce_quotes_at(&mut self, style: &QuoteStyle, selector: Option<&str>) -> Result<Vec<String>, YerbaError> {
|
|
818
812
|
let source = self.source_text();
|
|
819
813
|
|
|
820
|
-
let scope_ranges: Vec<TextRange> = match
|
|
821
|
-
Some(
|
|
814
|
+
let scope_ranges: Vec<TextRange> = match selector {
|
|
815
|
+
Some(scope) if !scope.is_empty() => self.navigate_all_compact(scope).iter().map(|node| node.text_range()).collect(),
|
|
822
816
|
_ => vec![self.root.text_range()],
|
|
823
817
|
};
|
|
824
818
|
|
|
@@ -869,7 +863,7 @@ impl Document {
|
|
|
869
863
|
}
|
|
870
864
|
|
|
871
865
|
if is_block_scalar_text && !is_block_scalar_target {
|
|
872
|
-
if
|
|
866
|
+
if selector.is_none() || selector == Some("") {
|
|
873
867
|
continue;
|
|
874
868
|
}
|
|
875
869
|
|
|
@@ -1075,3 +1069,10 @@ fn inline_quote_replacement(raw_value: &str, current_kind: SyntaxKind, style: &Q
|
|
|
1075
1069
|
_ => None,
|
|
1076
1070
|
}
|
|
1077
1071
|
}
|
|
1072
|
+
|
|
1073
|
+
fn entry_colon_position(entry: &SyntaxNode) -> Option<usize> {
|
|
1074
|
+
entry
|
|
1075
|
+
.children_with_tokens()
|
|
1076
|
+
.find(|element| element.kind() == SyntaxKind::COLON)
|
|
1077
|
+
.map(|colon| colon.text_range().start().into())
|
|
1078
|
+
}
|
data/rust/src/document/unique.rs
CHANGED
|
@@ -11,12 +11,12 @@ pub struct DuplicateInfo {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
impl Document {
|
|
14
|
-
pub fn unique(&mut self,
|
|
15
|
-
self.unique_with_options(
|
|
14
|
+
pub fn unique(&mut self, selector: &str, by: &str, remove: bool) -> Result<Vec<DuplicateInfo>, YerbaError> {
|
|
15
|
+
self.unique_with_options(selector, by, remove, false)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
pub fn unique_with_options(&mut self,
|
|
19
|
-
let current_node = self.navigate(
|
|
18
|
+
pub fn unique_with_options(&mut self, selector: &str, by: &str, remove: bool, allow_blank_duplicates: bool) -> Result<Vec<DuplicateInfo>, YerbaError> {
|
|
19
|
+
let current_node = self.navigate(selector)?;
|
|
20
20
|
let source = self.source_text();
|
|
21
21
|
|
|
22
22
|
let sequence = match find_block_sequence(¤t_node) {
|
|
@@ -76,7 +76,7 @@ impl Document {
|
|
|
76
76
|
|
|
77
77
|
if remove && !duplicate_indices.is_empty() {
|
|
78
78
|
for &index in duplicate_indices.iter().rev() {
|
|
79
|
-
self.remove_at(
|
|
79
|
+
self.remove_at(selector, index)?;
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
data/rust/src/error.rs
CHANGED
|
@@ -27,13 +27,13 @@ impl std::fmt::Display for YerbaError {
|
|
|
27
27
|
YerbaError::ParseError(msg) => write!(f, "parse error: {}", msg),
|
|
28
28
|
YerbaError::IoError(err) => write!(f, "io error: {}", err),
|
|
29
29
|
YerbaError::SelectorNotFound(selector) => write!(f, "selector not found: {}", selector),
|
|
30
|
-
YerbaError::NotASequence(
|
|
30
|
+
YerbaError::NotASequence(selector) => write!(f, "not a sequence: {}", selector),
|
|
31
31
|
|
|
32
|
-
YerbaError::FlowCollectionNotWritable(
|
|
32
|
+
YerbaError::FlowCollectionNotWritable(selector) => {
|
|
33
33
|
write!(
|
|
34
34
|
f,
|
|
35
35
|
"cannot write to \"{}\": flow collections are not writable yet. Convert it to block style first, with `collection_style` or `yerba collection-style`",
|
|
36
|
-
|
|
36
|
+
selector
|
|
37
37
|
)
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -170,7 +170,11 @@ impl GitHubAnnotations for YerbaError {
|
|
|
170
170
|
level: "error ",
|
|
171
171
|
file: file.to_string(),
|
|
172
172
|
line: Some(control.line),
|
|
173
|
-
message: format!(
|
|
173
|
+
message: format!(
|
|
174
|
+
"control character U+{:04X} at column {}",
|
|
175
|
+
control.character as u32,
|
|
176
|
+
control.character_column + 1
|
|
177
|
+
),
|
|
174
178
|
})
|
|
175
179
|
.collect(),
|
|
176
180
|
|