yerba 0.5.0-aarch64-linux-gnu → 0.6.0-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 +2 -26
- data/exe/aarch64-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +12 -0
- data/ext/yerba/yerba.c +74 -0
- 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/formatting.rb +61 -0
- data/lib/yerba/map.rb +50 -6
- data/lib/yerba/sequence.rb +20 -0
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +21 -21
- data/rust/Cargo.toml +2 -2
- data/rust/src/commands/get.rs +1 -1
- data/rust/src/commands/selectors.rs +4 -4
- data/rust/src/commands/sort.rs +1 -1
- data/rust/src/document/condition.rs +2 -2
- data/rust/src/document/delete.rs +65 -8
- data/rust/src/document/get.rs +55 -30
- data/rust/src/document/insert.rs +204 -9
- data/rust/src/document/mod.rs +76 -26
- data/rust/src/document/sort.rs +2 -2
- data/rust/src/document/style.rs +609 -2
- data/rust/src/ffi.rs +46 -0
- data/rust/src/json.rs +16 -16
- data/rust/src/lib.rs +3 -2
- data/rust/src/selector.rs +16 -0
- data/rust/src/yaml_writer.rs +98 -0
- data/rust/src/yerbafile.rs +164 -72
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 25f1b44c80d2fea571408d3db9e17d82480f3ec0bc9ba7c44f7facc374a7ff45
|
|
4
|
+
data.tar.gz: 0b6c9c732054bfe5c95c22587a3d0900128b533a2fb5445ebe7847ad17a6bad6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 15c96de98439438601d7c507aed217b0b96dc58afadf532d590ff1fc1d9650f65489a57b520c33878a82c60686e78f44955d5b940158cfbe2367613b5a1b141b
|
|
7
|
+
data.tar.gz: d7b3a4bf8f4b8943a0454845ab7a0c2ef9ea021b6d410e7667beecec461b7d12453b0437823b46556a7dabab7d2fd7730dca4fe01685bfa7c62fc03ec6cb23bf
|
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.
|
|
50
|
+
yerba = "0.5"
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
```rust
|
|
@@ -843,31 +843,7 @@ document.to_s
|
|
|
843
843
|
|
|
844
844
|
## Development
|
|
845
845
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
### Building from source
|
|
849
|
-
|
|
850
|
-
The Rust core is in the `rust/` directory, with a workspace `Cargo.toml` at the root so all cargo commands work from the project root:
|
|
851
|
-
|
|
852
|
-
```bash
|
|
853
|
-
cargo build
|
|
854
|
-
cargo test
|
|
855
|
-
```
|
|
856
|
-
|
|
857
|
-
The C extension (for the Ruby API) is compiled via `ext/yerba/extconf.rb` which invokes `cargo build` and links against the resulting static library. Running `bundle exec rake compile` will build both the Rust library and the C extension.
|
|
858
|
-
|
|
859
|
-
### Running the CLI locally
|
|
860
|
-
|
|
861
|
-
```bash
|
|
862
|
-
cargo run -- get config.yml "database.host"
|
|
863
|
-
```
|
|
864
|
-
|
|
865
|
-
Or build a release binary:
|
|
866
|
-
|
|
867
|
-
```bash
|
|
868
|
-
cargo build --release
|
|
869
|
-
./target/release/yerba --help
|
|
870
|
-
```
|
|
846
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to set up the repo locally, run tests, and contribute.
|
|
871
847
|
|
|
872
848
|
## License
|
|
873
849
|
|
data/exe/aarch64-linux-gnu/yerba
CHANGED
|
Binary file
|
data/ext/yerba/include/yerba.h
CHANGED
|
@@ -90,6 +90,18 @@ struct YerbaResult yerba_document_set_quote_style(struct Document *document,
|
|
|
90
90
|
const char *path,
|
|
91
91
|
const char *style);
|
|
92
92
|
|
|
93
|
+
char *yerba_document_get_collection_style(const struct Document *document, const char *path);
|
|
94
|
+
|
|
95
|
+
struct YerbaResult yerba_document_set_collection_style(struct Document *document,
|
|
96
|
+
const char *path,
|
|
97
|
+
const char *style);
|
|
98
|
+
|
|
99
|
+
char *yerba_document_get_sequence_indent(const struct Document *document, const char *path);
|
|
100
|
+
|
|
101
|
+
struct YerbaResult yerba_document_set_sequence_indent(struct Document *document,
|
|
102
|
+
const char *path,
|
|
103
|
+
const char *style);
|
|
104
|
+
|
|
93
105
|
bool yerba_document_evaluate_condition(const struct Document *document,
|
|
94
106
|
const char *parent_path,
|
|
95
107
|
const char *condition);
|
data/ext/yerba/yerba.c
CHANGED
|
@@ -374,6 +374,76 @@ static VALUE document_set_quote_style(VALUE self, VALUE path, VALUE style) {
|
|
|
374
374
|
return self;
|
|
375
375
|
}
|
|
376
376
|
|
|
377
|
+
/* document.get_collection_style(path) → :flow, :block, or nil */
|
|
378
|
+
static VALUE document_get_collection_style(VALUE self, VALUE path) {
|
|
379
|
+
struct Document *document = get_document(self);
|
|
380
|
+
char *style = yerba_document_get_collection_style(document, StringValueCStr(path));
|
|
381
|
+
|
|
382
|
+
if (style == NULL) return Qnil;
|
|
383
|
+
|
|
384
|
+
VALUE symbol = ID2SYM(rb_intern(style));
|
|
385
|
+
|
|
386
|
+
yerba_string_free(style);
|
|
387
|
+
|
|
388
|
+
return symbol;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* document.set_collection_style(path, style) */
|
|
392
|
+
static VALUE document_set_collection_style(VALUE self, VALUE path, VALUE style) {
|
|
393
|
+
struct Document *document = get_document(self);
|
|
394
|
+
|
|
395
|
+
const char *style_string;
|
|
396
|
+
|
|
397
|
+
if (RB_TYPE_P(style, T_SYMBOL)) {
|
|
398
|
+
style_string = rb_id2name(SYM2ID(style));
|
|
399
|
+
} else if (RB_TYPE_P(style, T_STRING)) {
|
|
400
|
+
style_string = StringValueCStr(style);
|
|
401
|
+
} else {
|
|
402
|
+
rb_raise(rb_eError, "Invalid collection style (expected Symbol or String)");
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(path), style_string);
|
|
406
|
+
|
|
407
|
+
check_result(result);
|
|
408
|
+
|
|
409
|
+
return self;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* document.get_sequence_indent(path) → :compact, :indented, or nil */
|
|
413
|
+
static VALUE document_get_sequence_indent(VALUE self, VALUE path) {
|
|
414
|
+
struct Document *document = get_document(self);
|
|
415
|
+
char *style = yerba_document_get_sequence_indent(document, StringValueCStr(path));
|
|
416
|
+
|
|
417
|
+
if (style == NULL) return Qnil;
|
|
418
|
+
|
|
419
|
+
VALUE symbol = ID2SYM(rb_intern(style));
|
|
420
|
+
|
|
421
|
+
yerba_string_free(style);
|
|
422
|
+
|
|
423
|
+
return symbol;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/* document.set_sequence_indent(path, style) */
|
|
427
|
+
static VALUE document_set_sequence_indent(VALUE self, VALUE path, VALUE style) {
|
|
428
|
+
struct Document *document = get_document(self);
|
|
429
|
+
|
|
430
|
+
const char *style_string;
|
|
431
|
+
|
|
432
|
+
if (RB_TYPE_P(style, T_SYMBOL)) {
|
|
433
|
+
style_string = rb_id2name(SYM2ID(style));
|
|
434
|
+
} else if (RB_TYPE_P(style, T_STRING)) {
|
|
435
|
+
style_string = StringValueCStr(style);
|
|
436
|
+
} else {
|
|
437
|
+
rb_raise(rb_eError, "Invalid sequence indent style (expected Symbol or String)");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(path), style_string);
|
|
441
|
+
|
|
442
|
+
check_result(result);
|
|
443
|
+
|
|
444
|
+
return self;
|
|
445
|
+
}
|
|
446
|
+
|
|
377
447
|
/* document.condition?(condition, path: "") */
|
|
378
448
|
static VALUE document_condition_p(int argc, VALUE *argv, VALUE self) {
|
|
379
449
|
VALUE condition, opts;
|
|
@@ -965,6 +1035,10 @@ void Init_yerba(void) {
|
|
|
965
1035
|
rb_define_method(rb_cDocument, "resolve_selectors", document_resolve_selectors, 1);
|
|
966
1036
|
rb_define_method(rb_cDocument, "get_quote_style", document_get_quote_style, 1);
|
|
967
1037
|
rb_define_method(rb_cDocument, "set_quote_style", document_set_quote_style, 2);
|
|
1038
|
+
rb_define_method(rb_cDocument, "get_collection_style", document_get_collection_style, 1);
|
|
1039
|
+
rb_define_method(rb_cDocument, "set_collection_style", document_set_collection_style, 2);
|
|
1040
|
+
rb_define_method(rb_cDocument, "get_sequence_indent", document_get_sequence_indent, 1);
|
|
1041
|
+
rb_define_method(rb_cDocument, "set_sequence_indent", document_set_sequence_indent, 2);
|
|
968
1042
|
rb_define_method(rb_cDocument, "exists?", document_exists_p, 1);
|
|
969
1043
|
rb_define_method(rb_cDocument, "valid_selector?", document_valid_selector_p, 1);
|
|
970
1044
|
rb_define_method(rb_cDocument, "condition?", document_condition_p, -1);
|
data/lib/yerba/3.2/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/3.3/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/3.4/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/4.0/yerba.so
CHANGED
|
Binary file
|
data/lib/yerba/formatting.rb
CHANGED
|
@@ -14,5 +14,66 @@ module Yerba
|
|
|
14
14
|
value.to_s
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
+
|
|
18
|
+
def self.to_yaml_value(value)
|
|
19
|
+
case value
|
|
20
|
+
when Array
|
|
21
|
+
return "[]" if value.empty?
|
|
22
|
+
|
|
23
|
+
items = value.map { |item| to_yaml_value(item) }
|
|
24
|
+
|
|
25
|
+
"[#{items.join(", ")}]"
|
|
26
|
+
when Hash
|
|
27
|
+
return "{}" if value.empty?
|
|
28
|
+
|
|
29
|
+
pairs = value.map { |key, value| "#{key}: #{to_yaml_value(value)}" }
|
|
30
|
+
|
|
31
|
+
"{#{pairs.join(", ")}}"
|
|
32
|
+
when true then "true"
|
|
33
|
+
when false then "false"
|
|
34
|
+
when nil then "null"
|
|
35
|
+
else value.to_s
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.to_block_yaml_value(value, indent = 0)
|
|
40
|
+
prefix = " " * indent
|
|
41
|
+
|
|
42
|
+
case value
|
|
43
|
+
when Array
|
|
44
|
+
return "[]" if value.empty?
|
|
45
|
+
|
|
46
|
+
value.map { |item|
|
|
47
|
+
if item.is_a?(Hash)
|
|
48
|
+
inner = to_block_yaml_value(item, indent + 1)
|
|
49
|
+
"#{prefix}- #{inner.lstrip}"
|
|
50
|
+
else
|
|
51
|
+
"#{prefix}- #{to_scalar_value(item)}"
|
|
52
|
+
end
|
|
53
|
+
}.join("\n")
|
|
54
|
+
when Hash
|
|
55
|
+
return "{}" if value.empty?
|
|
56
|
+
|
|
57
|
+
value.map { |key, value|
|
|
58
|
+
if value.is_a?(Hash) || value.is_a?(Array)
|
|
59
|
+
inner = to_block_yaml_value(value, indent + 1)
|
|
60
|
+
"#{prefix}#{key}:\n#{inner}"
|
|
61
|
+
else
|
|
62
|
+
"#{prefix}#{key}: #{to_scalar_value(value)}"
|
|
63
|
+
end
|
|
64
|
+
}.join("\n")
|
|
65
|
+
else
|
|
66
|
+
to_scalar_value(value)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.to_scalar_value(value)
|
|
71
|
+
case value
|
|
72
|
+
when true then "true"
|
|
73
|
+
when false then "false"
|
|
74
|
+
when nil then "null"
|
|
75
|
+
else value.to_s
|
|
76
|
+
end
|
|
77
|
+
end
|
|
17
78
|
end
|
|
18
79
|
end
|
data/lib/yerba/map.rb
CHANGED
|
@@ -25,24 +25,44 @@ module Yerba
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def []=(key, value)
|
|
28
|
+
set(key, value)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def set(key, value, style: nil)
|
|
28
32
|
if connected?
|
|
29
33
|
new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
coerced = coerce_value(value, style: style)
|
|
35
|
+
is_block_value = coerced.is_a?(String) && (coerced.include?("\n") || coerced.start_with?("- "))
|
|
36
|
+
|
|
37
|
+
if document.exists?(new_path) && is_block_value
|
|
38
|
+
# Block-style collections can't replace a scalar via set().
|
|
39
|
+
# Delete the key and re-insert at the same position.
|
|
40
|
+
all_keys = keys
|
|
41
|
+
key_index = all_keys.index(key.to_s)
|
|
42
|
+
after_key = key_index&.positive? ? all_keys[key_index - 1] : nil
|
|
43
|
+
|
|
44
|
+
document.delete(new_path)
|
|
45
|
+
|
|
46
|
+
if after_key
|
|
47
|
+
document.insert(new_path, coerced, after: after_key)
|
|
48
|
+
else
|
|
49
|
+
document.insert(new_path, coerced)
|
|
50
|
+
end
|
|
51
|
+
elsif document.exists?(new_path)
|
|
52
|
+
document.set(new_path, coerced)
|
|
33
53
|
else
|
|
34
|
-
document.insert(new_path,
|
|
54
|
+
document.insert(new_path, coerced)
|
|
35
55
|
end
|
|
36
56
|
else
|
|
37
57
|
@data[key] = value
|
|
38
58
|
end
|
|
39
59
|
end
|
|
40
60
|
|
|
41
|
-
def insert(key, value, before: nil, after: nil)
|
|
61
|
+
def insert(key, value, before: nil, after: nil, style: nil)
|
|
42
62
|
if connected?
|
|
43
63
|
new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
|
|
44
64
|
|
|
45
|
-
document.insert(new_path, value, before: before, after: after)
|
|
65
|
+
document.insert(new_path, coerce_value(value, style: style), before: before, after: after)
|
|
46
66
|
else
|
|
47
67
|
@data[key] = value
|
|
48
68
|
end
|
|
@@ -165,6 +185,16 @@ module Yerba
|
|
|
165
185
|
end
|
|
166
186
|
end
|
|
167
187
|
|
|
188
|
+
def collection_style
|
|
189
|
+
@collection_style || document&.get_collection_style(@selector)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def collection_style=(style)
|
|
193
|
+
document&.set_collection_style(@selector, style)
|
|
194
|
+
|
|
195
|
+
@collection_style = style
|
|
196
|
+
end
|
|
197
|
+
|
|
168
198
|
private
|
|
169
199
|
|
|
170
200
|
def format_value(value)
|
|
@@ -174,5 +204,19 @@ module Yerba
|
|
|
174
204
|
else value.to_s
|
|
175
205
|
end
|
|
176
206
|
end
|
|
207
|
+
|
|
208
|
+
def coerce_value(value, style: nil)
|
|
209
|
+
case value
|
|
210
|
+
when Array, Hash
|
|
211
|
+
resolved_style = style || :block
|
|
212
|
+
|
|
213
|
+
if resolved_style == :flow
|
|
214
|
+
Formatting.to_yaml_value(value)
|
|
215
|
+
else
|
|
216
|
+
Formatting.to_block_yaml_value(value)
|
|
217
|
+
end
|
|
218
|
+
else value
|
|
219
|
+
end
|
|
220
|
+
end
|
|
177
221
|
end
|
|
178
222
|
end
|
data/lib/yerba/sequence.rb
CHANGED
|
@@ -293,6 +293,26 @@ module Yerba
|
|
|
293
293
|
end
|
|
294
294
|
end
|
|
295
295
|
|
|
296
|
+
def collection_style
|
|
297
|
+
@collection_style || document&.get_collection_style(@selector)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def collection_style=(style)
|
|
301
|
+
document&.set_collection_style(@selector, style)
|
|
302
|
+
|
|
303
|
+
@collection_style = style
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def sequence_indent
|
|
307
|
+
@sequence_indent || document&.get_sequence_indent(@selector)
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def sequence_indent=(style)
|
|
311
|
+
document&.set_sequence_indent(@selector, style)
|
|
312
|
+
|
|
313
|
+
@sequence_indent = style
|
|
314
|
+
end
|
|
315
|
+
|
|
296
316
|
private
|
|
297
317
|
|
|
298
318
|
def dig_into(hash, path)
|
data/lib/yerba/version.rb
CHANGED
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.
|
|
1775
|
+
version = "0.6.0"
|
|
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.
|
|
3
|
+
version = "0.6.0"
|
|
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
|
-
|
|
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"
|
data/rust/src/commands/get.rs
CHANGED
|
@@ -112,7 +112,7 @@ impl Args {
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
let (values, selectors, lines): (Vec<
|
|
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: &
|
|
119
|
+
fn collect_selectors(value: &yaml_serde::Value, prefix: &str, selectors: &mut BTreeMap<String, SelectorInfo>, counter: &mut usize) {
|
|
120
120
|
match value {
|
|
121
|
-
|
|
121
|
+
yaml_serde::Value::Mapping(map) => {
|
|
122
122
|
for (key, child) in map {
|
|
123
|
-
if let
|
|
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
|
-
|
|
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();
|
data/rust/src/commands/sort.rs
CHANGED
|
@@ -329,7 +329,7 @@ impl Args {
|
|
|
329
329
|
.map(|item| {
|
|
330
330
|
if by_is_scalar {
|
|
331
331
|
match item {
|
|
332
|
-
|
|
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<
|
|
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<(
|
|
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
|
data/rust/src/document/delete.rs
CHANGED
|
@@ -35,17 +35,74 @@ 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
|
|
39
|
-
let
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
match last_segment {
|
|
44
|
+
crate::selector::SelectorSegment::Key(last_key) => {
|
|
45
|
+
let has_wildcard = selector.has_wildcard() || selector.has_brackets();
|
|
46
|
+
|
|
47
|
+
if parent_path.is_empty() && !has_wildcard {
|
|
48
|
+
let parent_node = self.navigate(&parent_path)?;
|
|
49
|
+
let map = parent_node
|
|
50
|
+
.descendants()
|
|
51
|
+
.find_map(BlockMap::cast)
|
|
52
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
53
|
+
|
|
54
|
+
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
55
|
+
|
|
56
|
+
return self.remove_map_entry(&entry);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let parent_nodes = self.navigate_all_compact(&parent_path);
|
|
60
|
+
|
|
61
|
+
if parent_nodes.is_empty() {
|
|
62
|
+
if has_wildcard {
|
|
63
|
+
return Ok(());
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return Err(YerbaError::SelectorNotFound(dot_path.to_string()));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if parent_nodes.len() == 1 && !has_wildcard {
|
|
70
|
+
let map = parent_nodes[0]
|
|
71
|
+
.descendants()
|
|
72
|
+
.find_map(BlockMap::cast)
|
|
73
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
45
74
|
|
|
46
|
-
|
|
75
|
+
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(dot_path.to_string()))?;
|
|
47
76
|
|
|
48
|
-
|
|
77
|
+
return self.remove_map_entry(&entry);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let mut ranges: Vec<TextRange> = Vec::new();
|
|
81
|
+
|
|
82
|
+
for parent_node in &parent_nodes {
|
|
83
|
+
if let Some(map) = parent_node.descendants().find_map(BlockMap::cast) {
|
|
84
|
+
if let Some(entry) = find_entry_by_key(&map, last_key) {
|
|
85
|
+
ranges.push(removal_range(entry.syntax()));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if ranges.is_empty() {
|
|
91
|
+
return Ok(());
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
ranges.reverse();
|
|
95
|
+
|
|
96
|
+
for range in ranges {
|
|
97
|
+
self.apply_edit(range, "")?;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Ok(())
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_path, *index),
|
|
104
|
+
crate::selector::SelectorSegment::AllItems => Err(YerbaError::SelectorNotFound(dot_path.to_string())),
|
|
105
|
+
}
|
|
49
106
|
}
|
|
50
107
|
|
|
51
108
|
pub fn remove(&mut self, dot_path: &str, value: &str) -> Result<(), YerbaError> {
|