yerba 0.4.2-x86_64-linux-gnu → 0.5.0-x86_64-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 +241 -53
- data/exe/x86_64-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +13 -1
- data/ext/yerba/yerba.c +239 -113
- 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/document.rb +54 -18
- data/lib/yerba/map.rb +55 -43
- data/lib/yerba/node.rb +58 -0
- data/lib/yerba/scalar.rb +20 -23
- data/lib/yerba/sequence.rb +88 -55
- data/lib/yerba/version.rb +1 -1
- data/lib/yerba.rb +2 -0
- data/rust/Cargo.lock +1110 -25
- data/rust/Cargo.toml +2 -1
- data/rust/src/commands/delete.rs +1 -1
- data/rust/src/commands/get.rs +47 -12
- data/rust/src/commands/insert.rs +1 -1
- data/rust/src/commands/location.rs +56 -0
- data/rust/src/commands/mod.rs +33 -5
- data/rust/src/commands/remove.rs +1 -1
- data/rust/src/commands/rename.rs +1 -1
- data/rust/src/commands/schema.rs +84 -0
- data/rust/src/commands/set.rs +1 -1
- data/rust/src/commands/unique.rs +80 -0
- data/rust/src/document/condition.rs +17 -1
- data/rust/src/document/get.rs +254 -23
- data/rust/src/document/mod.rs +90 -12
- data/rust/src/document/schema.rs +73 -0
- data/rust/src/document/set.rs +1 -1
- data/rust/src/document/sort.rs +19 -13
- data/rust/src/document/style.rs +3 -3
- data/rust/src/document/unique.rs +86 -0
- data/rust/src/error.rs +78 -0
- data/rust/src/ffi.rs +89 -9
- data/rust/src/lib.rs +5 -10
- data/rust/src/main.rs +2 -0
- data/rust/src/schema.rs +93 -0
- data/rust/src/syntax.rs +91 -31
- data/rust/src/yerbafile.rs +107 -18
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 497a769ee07b1e766ff7e0f991212be8268e475d1e5a9cc882e9f62845390401
|
|
4
|
+
data.tar.gz: d7e66c881d9547477d3ea8ebc232e52141a561a063179cf3534ad9c0090e1ad2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5fc61b863455ba54bb41f63da74d32114e62cc54c2f467534ce6da158b3c8ef820defe227de73179f8b013b9ec4d1824ca8c850f7538f7d0305b215c944d2279
|
|
7
|
+
data.tar.gz: 6d6a96b09dc0536f5704e43da759b75c0404d60c89d7ec6691bc1d3313d7f9ac0cfa755836de18dfcf224a57ca42f0afdfb19303a661ee3fc3c8b0e19d20f3a1
|
data/README.md
CHANGED
|
@@ -90,24 +90,24 @@ Selectors use dot-notation for nested keys, brackets for array access, and suppo
|
|
|
90
90
|
|
|
91
91
|
Selectors let you address any node in a YAML document:
|
|
92
92
|
|
|
93
|
-
| Pattern
|
|
94
|
-
|
|
95
|
-
| `key`
|
|
96
|
-
| `key.nested`
|
|
97
|
-
| `[]`
|
|
98
|
-
| `[N]`
|
|
99
|
-
| `[].key[].nested` | Nested array access | `"[].speakers[].name"`
|
|
93
|
+
| Pattern | Meaning | Example |
|
|
94
|
+
|-------------------|---------------------|----------------------------|
|
|
95
|
+
| `key` | A single key | `"database.host"` |
|
|
96
|
+
| `key.nested` | Nested key path | `"database.settings.pool"` |
|
|
97
|
+
| `[]` | All items in array | `"[].title"` |
|
|
98
|
+
| `[N]` | Item at index | `"[0].title"` |
|
|
99
|
+
| `[].key[].nested` | Nested array access | `"[].speakers[].name"` |
|
|
100
100
|
|
|
101
101
|
### Conditions
|
|
102
102
|
|
|
103
103
|
Conditions filter which items a command operates on:
|
|
104
104
|
|
|
105
|
-
| Syntax
|
|
106
|
-
|
|
107
|
-
| `.key == value`
|
|
108
|
-
| `.key != value`
|
|
109
|
-
| `.key contains val`
|
|
110
|
-
| `.key not_contains val` | Negated contains
|
|
105
|
+
| Syntax | Meaning | Example |
|
|
106
|
+
|-------------------------|---------------------|------------------------------|
|
|
107
|
+
| `.key == value` | Equality | `".kind == keynote"` |
|
|
108
|
+
| `.key != value` | Inequality | `".status != draft"` |
|
|
109
|
+
| `.key contains val` | Substring or member | `".title contains Ruby"` |
|
|
110
|
+
| `.key not_contains val` | Negated contains | `".title not_contains test"` |
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
@@ -311,25 +311,25 @@ yerba quote-style videos.yml "[].description" --values literal
|
|
|
311
311
|
|
|
312
312
|
**Key styles** (`--keys`):
|
|
313
313
|
|
|
314
|
-
| Style
|
|
315
|
-
|
|
316
|
-
| `plain`
|
|
317
|
-
| `single` | `'`
|
|
318
|
-
| `double` | `"`
|
|
314
|
+
| Style | Symbol | Example |
|
|
315
|
+
|----------|--------|-----------------|
|
|
316
|
+
| `plain` | — | `host: value` |
|
|
317
|
+
| `single` | `'` | `'host': value` |
|
|
318
|
+
| `double` | `"` | `"host": value` |
|
|
319
319
|
|
|
320
320
|
**Value styles** (`--values`):
|
|
321
321
|
|
|
322
|
-
| Style
|
|
323
|
-
|
|
324
|
-
| `plain`
|
|
325
|
-
| `single`
|
|
326
|
-
| `double`
|
|
327
|
-
| `literal` |
|
|
328
|
-
| `literal-clip` |
|
|
329
|
-
| `literal-keep` |
|
|
330
|
-
| `folded`
|
|
331
|
-
| `folded-clip`
|
|
332
|
-
| `folded-keep`
|
|
322
|
+
| Style | Symbol | Example | Behavior | |
|
|
323
|
+
|----------------|--------|--------------------------|--------------------------------------|----------------------------|
|
|
324
|
+
| `plain` | — | `host: localhost` | Unquoted | |
|
|
325
|
+
| `single` | `'` | `host: 'localhost'` | Single-quoted | |
|
|
326
|
+
| `double` | `"` | `host: "localhost"` | Double-quoted, supports `\n` escapes | |
|
|
327
|
+
| `literal` | `\ | -` | Preserves newlines | Strip trailing newline |
|
|
328
|
+
| `literal-clip` | `\ | ` | Preserves newlines | Keep one trailing newline |
|
|
329
|
+
| `literal-keep` | `\ | +` | Preserves newlines | Keep all trailing newlines |
|
|
330
|
+
| `folded` | `>-` | Folds newlines to spaces | Strip trailing newline | |
|
|
331
|
+
| `folded-clip` | `>` | Folds newlines to spaces | Keep one trailing newline | |
|
|
332
|
+
| `folded-keep` | `>+` | Folds newlines to spaces | Keep all trailing newlines | |
|
|
333
333
|
|
|
334
334
|
Block scalars are only converted when scoped to a specific selector. An unscoped `--values double` will not touch existing block scalars.
|
|
335
335
|
|
|
@@ -353,6 +353,63 @@ yerba directives config.yml --remove
|
|
|
353
353
|
yerba directives "data/**/*.yml" --ensure
|
|
354
354
|
```
|
|
355
355
|
|
|
356
|
+
### `unique`
|
|
357
|
+
|
|
358
|
+
Find or remove duplicate items in a sequence. Use `--by` to specify which field determines uniqueness:
|
|
359
|
+
|
|
360
|
+
```bash
|
|
361
|
+
yerba unique videos.yml --by ".id"
|
|
362
|
+
yerba unique speakers.yml --by ".name"
|
|
363
|
+
yerba unique config.yml "tags" --by "."
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
By default, duplicates are reported but not removed. Use `--remove` to remove them (keeps the first occurrence):
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
yerba unique videos.yml --by ".id" --remove
|
|
370
|
+
yerba unique speakers.yml --by ".name" --remove --dry-run
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### `location`
|
|
374
|
+
|
|
375
|
+
Show the location (line, column, byte offset) of a selector in a YAML file:
|
|
376
|
+
|
|
377
|
+
```bash
|
|
378
|
+
yerba location config.yml "database.host"
|
|
379
|
+
yerba location videos.yml "[0].title"
|
|
380
|
+
yerba location videos.yml "[0]"
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Output:
|
|
384
|
+
```json
|
|
385
|
+
{
|
|
386
|
+
"selector": "[0].title",
|
|
387
|
+
"file": "videos.yml",
|
|
388
|
+
"start_line": 2,
|
|
389
|
+
"start_column": 9,
|
|
390
|
+
"end_line": 2,
|
|
391
|
+
"end_column": 19,
|
|
392
|
+
"start_offset": 22,
|
|
393
|
+
"end_offset": 32
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### `schema`
|
|
398
|
+
|
|
399
|
+
Validate YAML files against a JSON schema:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
yerba schema data/speakers.yml --schema lib/schemas/speaker_schema.json
|
|
403
|
+
yerba schema "data/**/videos.yml" --schema lib/schemas/video_schema.json
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
Use `--path` to scope validation to a specific selector (e.g. validate each item in an array):
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
yerba schema data/speakers.yml --schema speaker_schema.json --selector "[]"
|
|
410
|
+
yerba schema data/sponsors.yml --schema tier_schema.json --selector "tiers[]"
|
|
411
|
+
```
|
|
412
|
+
|
|
356
413
|
### `selectors`
|
|
357
414
|
|
|
358
415
|
Show all valid selectors for a YAML file. Useful for discovering the structure of a file and knowing which selectors you can use with other commands:
|
|
@@ -471,6 +528,8 @@ Available pipeline steps:
|
|
|
471
528
|
- `rename` Rename a key
|
|
472
529
|
- `remove` Remove an item from a sequence
|
|
473
530
|
- `directives` Add or remove the document start marker (`---`)
|
|
531
|
+
- `unique` Find or remove duplicate items in a sequence
|
|
532
|
+
- `schema` Validate against a JSON schema (with optional `path` for scoping)
|
|
474
533
|
- `get` Read a value and store it as a variable for subsequent steps
|
|
475
534
|
|
|
476
535
|
This makes it easy to enforce project-wide YAML conventions in CI:
|
|
@@ -491,47 +550,74 @@ Create a document from a file path or from a string:
|
|
|
491
550
|
require "yerba"
|
|
492
551
|
|
|
493
552
|
document = Yerba.parse_file("config.yml")
|
|
494
|
-
|
|
553
|
+
|
|
554
|
+
document = Yerba.parse(<<~YAML)
|
|
555
|
+
database:
|
|
556
|
+
host: localhost
|
|
557
|
+
port: 5432
|
|
558
|
+
YAML
|
|
495
559
|
```
|
|
496
560
|
|
|
497
561
|
### Reading Values
|
|
498
562
|
|
|
499
|
-
Use `
|
|
563
|
+
Use bracket notation (`[]`) to navigate the document. Returns typed node objects (`Scalar`, `Map`, or `Sequence`) that are live references — mutations flow back to the document.
|
|
564
|
+
|
|
565
|
+
All access methods (`[]`, `fetch`, `dig`, `value_at`) accept full selector strings like `"database.host"`, `"[0].title"`, or `"[].speakers[].name"`. In the examples below we prefer the more idiomatic chained bracket style, but the two forms are equivalent:
|
|
500
566
|
|
|
501
567
|
```ruby
|
|
502
|
-
document
|
|
503
|
-
document
|
|
504
|
-
document.get("database.ssl") # => false
|
|
568
|
+
document["database"]["host"].value # => "localhost"
|
|
569
|
+
document["database.host"].value # => "localhost" (same thing)
|
|
505
570
|
```
|
|
506
571
|
|
|
507
|
-
|
|
572
|
+
The returned object type depends on what's at the path:
|
|
508
573
|
|
|
509
|
-
|
|
574
|
+
```ruby
|
|
575
|
+
document["database"] # => Yerba::Map
|
|
576
|
+
document["database"]["host"] # => Yerba::Scalar
|
|
577
|
+
document["tags"] # => Yerba::Sequence
|
|
578
|
+
```
|
|
510
579
|
|
|
511
|
-
|
|
580
|
+
Scalars expose their value and quote style:
|
|
512
581
|
|
|
513
582
|
```ruby
|
|
514
|
-
document["database
|
|
515
|
-
|
|
516
|
-
|
|
583
|
+
scalar = document["database"]["host"]
|
|
584
|
+
scalar.value # => "localhost"
|
|
585
|
+
scalar.quote_style # => :double
|
|
517
586
|
```
|
|
518
587
|
|
|
519
|
-
|
|
588
|
+
Use `fetch` for strict access, it raises `Yerba::SelectorNotFoundError` with "did you mean?" suggestions if the selector doesn't exist:
|
|
520
589
|
|
|
521
590
|
```ruby
|
|
522
|
-
document
|
|
523
|
-
document
|
|
524
|
-
document["tags"] # => Yerba::Sequence
|
|
591
|
+
document.fetch("database.host") # => Yerba::Scalar
|
|
592
|
+
document.fetch("databse.host") # => raises SelectorNotFoundError: ... Did you mean: database.host?
|
|
525
593
|
```
|
|
526
594
|
|
|
527
|
-
|
|
595
|
+
Use `dig` to traverse multiple levels, returning `nil` for missing paths:
|
|
596
|
+
|
|
597
|
+
```ruby
|
|
598
|
+
document.dig("database", "host") # => Yerba::Scalar
|
|
599
|
+
document.dig("items", 0, "name") # => Yerba::Scalar
|
|
600
|
+
document.dig("database", "missing") # => nil
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Use `value_at` to get the plain Ruby value (String, Integer, Hash, Array, etc.) instead of a node object:
|
|
528
604
|
|
|
529
605
|
```ruby
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
606
|
+
document.value_at("database.host") # => "localhost"
|
|
607
|
+
document.value_at("database.port") # => 5432
|
|
608
|
+
document.value_at("database") # => {"host" => "localhost", "port" => 5432}
|
|
609
|
+
document.value_at("[].title") # => ["First Talk", "Second Talk"]
|
|
533
610
|
```
|
|
534
611
|
|
|
612
|
+
Summary of access methods:
|
|
613
|
+
|
|
614
|
+
| Method | Not found | Returns |
|
|
615
|
+
|------------|--------------------------------|------------------------------------|
|
|
616
|
+
| `[]` | `nil` | `Scalar` / `Map` / `Sequence` node |
|
|
617
|
+
| `fetch` | raises `SelectorNotFoundError` | `Scalar` / `Map` / `Sequence` node |
|
|
618
|
+
| `dig` | `nil` | `Scalar` / `Map` / `Sequence` node |
|
|
619
|
+
| `value_at` | `nil` | plain Ruby value |
|
|
620
|
+
|
|
535
621
|
### Mutations
|
|
536
622
|
|
|
537
623
|
Modify values in place. The original formatting is preserved:
|
|
@@ -600,23 +686,99 @@ collection.where(kind: "talk")
|
|
|
600
686
|
collection.pluck(:name)
|
|
601
687
|
```
|
|
602
688
|
|
|
689
|
+
### Schema Validation
|
|
690
|
+
|
|
691
|
+
Validate documents against JSON schemas from Ruby:
|
|
692
|
+
|
|
693
|
+
```ruby
|
|
694
|
+
schema = {
|
|
695
|
+
type: "object",
|
|
696
|
+
properties: { name: { type: "string" }, slug: { type: "string" } },
|
|
697
|
+
required: ["name", "slug"]
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
document.valid?(schema) # => true/false
|
|
701
|
+
document.valid?(schema, selector: "[]") # validate each array item
|
|
702
|
+
|
|
703
|
+
errors = document.validate(schema, selector: "[]")
|
|
704
|
+
|
|
705
|
+
errors.each do |error|
|
|
706
|
+
puts "#{error["message"]} at #{error["path"]} (line #{error["line"]})"
|
|
707
|
+
end
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
Also accepts a JSON string:
|
|
711
|
+
|
|
712
|
+
```ruby
|
|
713
|
+
document.valid?('{"type":"object","required":["name"]}')
|
|
714
|
+
```
|
|
715
|
+
|
|
603
716
|
### Quote Style Control
|
|
604
717
|
|
|
605
718
|
Read and set the quote style on individual scalars:
|
|
606
719
|
|
|
607
720
|
```ruby
|
|
608
|
-
scalar = document["database
|
|
721
|
+
scalar = document["database"]["host"]
|
|
609
722
|
scalar.quote_style # => :double
|
|
610
723
|
scalar.quote_style = :single
|
|
611
724
|
```
|
|
612
725
|
|
|
726
|
+
### Location
|
|
727
|
+
|
|
728
|
+
Get the precise location (line, column, byte offset) of any selector in a document:
|
|
729
|
+
|
|
730
|
+
```ruby
|
|
731
|
+
loc = document[0]["title"].location
|
|
732
|
+
loc.start_line # => 2
|
|
733
|
+
loc.start_column # => 9
|
|
734
|
+
loc.end_line # => 2
|
|
735
|
+
loc.end_column # => 19
|
|
736
|
+
loc.start_offset # => 22
|
|
737
|
+
loc.end_offset # => 32
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
You can also get a location by selector string:
|
|
741
|
+
|
|
742
|
+
```ruby
|
|
743
|
+
document.location("[0].title")
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
The above is the same as:
|
|
747
|
+
|
|
748
|
+
```ruby
|
|
749
|
+
document[0]["title"].location
|
|
750
|
+
document["[0].title"].location
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
Omit the selector to get the whole document's location:
|
|
754
|
+
|
|
755
|
+
```ruby
|
|
756
|
+
document.location # => #<Yerba::Location start_line=1, ...>
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
Returns `nil` for non-existent selectors. Use `locations` for wildcard selectors that match multiple nodes:
|
|
760
|
+
|
|
761
|
+
```ruby
|
|
762
|
+
locs = document.locations("[].title")
|
|
763
|
+
locs.each { |loc| puts "line #{loc.start_line}" }
|
|
764
|
+
# line 2
|
|
765
|
+
# line 4
|
|
766
|
+
|
|
767
|
+
document.locations("[]")
|
|
768
|
+
document.locations("[].speakers[]")
|
|
769
|
+
```
|
|
770
|
+
|
|
613
771
|
### Wildcard Access
|
|
614
772
|
|
|
615
|
-
|
|
773
|
+
When `[]` receives a wildcard selector (containing `[]`), it returns an array of nodes instead of a single node:
|
|
616
774
|
|
|
617
775
|
```ruby
|
|
618
|
-
|
|
619
|
-
|
|
776
|
+
document["[].title"] # => [Yerba::Scalar, Yerba::Scalar, ...]
|
|
777
|
+
document["[].speakers[]"] # => [Yerba::Scalar, Yerba::Scalar, ...]
|
|
778
|
+
document["items[].name"] # => [Yerba::Scalar, Yerba::Scalar, ...]
|
|
779
|
+
|
|
780
|
+
document["[].title"].each { |scalar| puts scalar.value }
|
|
781
|
+
document["[].title"].each { |scalar| scalar.value = "Updated" }
|
|
620
782
|
```
|
|
621
783
|
|
|
622
784
|
### Collections
|
|
@@ -627,7 +789,7 @@ Operate on multiple files matching a glob pattern:
|
|
|
627
789
|
collection = Yerba.files("data/**/videos.yml")
|
|
628
790
|
|
|
629
791
|
collection.each do |document|
|
|
630
|
-
puts document
|
|
792
|
+
puts document[0]["title"].value
|
|
631
793
|
end
|
|
632
794
|
|
|
633
795
|
collection.find_by(name: "Alice")
|
|
@@ -639,6 +801,32 @@ collection.apply! do |document|
|
|
|
639
801
|
end
|
|
640
802
|
```
|
|
641
803
|
|
|
804
|
+
Use `Collection.get` to retrieve nodes across all matching files in parallel. Returns `Scalar`, `Map`, or `Sequence` objects with `file_path`, `line`, and `selector`:
|
|
805
|
+
|
|
806
|
+
```ruby
|
|
807
|
+
speakers = Yerba::Collection.get("data/**/videos.yml", "[].speakers[]")
|
|
808
|
+
|
|
809
|
+
speakers.each do |scalar|
|
|
810
|
+
puts "#{scalar.value} in #{scalar.file_path}:#{scalar.line}"
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
maps = Yerba::Collection.get("data/**/videos.yml", "[]")
|
|
814
|
+
maps.first.class
|
|
815
|
+
# => Yerba::Map
|
|
816
|
+
|
|
817
|
+
sequences = Yerba::Collection.get("data/**/videos.yml", "[].speakers")
|
|
818
|
+
sequences.first.class
|
|
819
|
+
# => Yerba::Sequence
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
Nodes returned by `Collection.get` lazily load their `Document` on first mutation, so reads are fast and writes work transparently:
|
|
823
|
+
|
|
824
|
+
```ruby
|
|
825
|
+
scalars = Yerba::Collection.get("data/**/videos.yml", "[].title")
|
|
826
|
+
scalars.first.value = "New Title"
|
|
827
|
+
scalars.first.document.save!
|
|
828
|
+
```
|
|
829
|
+
|
|
642
830
|
### Saving
|
|
643
831
|
|
|
644
832
|
Write changes back to the original file:
|
data/exe/x86_64-linux-gnu/yerba
CHANGED
|
Binary file
|
data/ext/yerba/include/yerba.h
CHANGED
|
@@ -80,7 +80,9 @@ char *yerba_document_get_value(const struct Document *document, const char *path
|
|
|
80
80
|
/**
|
|
81
81
|
* Caller must free with yerba_string_free.
|
|
82
82
|
*/
|
|
83
|
-
char *
|
|
83
|
+
char *yerba_document_selectors(const struct Document *document);
|
|
84
|
+
|
|
85
|
+
char *yerba_document_resolve_selectors(const struct Document *document, const char *path);
|
|
84
86
|
|
|
85
87
|
char *yerba_document_get_quote_style(const struct Document *document, const char *path);
|
|
86
88
|
|
|
@@ -94,6 +96,8 @@ bool yerba_document_evaluate_condition(const struct Document *document,
|
|
|
94
96
|
|
|
95
97
|
bool yerba_document_exists(const struct Document *document, const char *path);
|
|
96
98
|
|
|
99
|
+
bool yerba_document_valid_selector(const struct Document *document, const char *path);
|
|
100
|
+
|
|
97
101
|
char *yerba_document_find(const struct Document *document,
|
|
98
102
|
const char *path,
|
|
99
103
|
const char *condition,
|
|
@@ -108,6 +112,7 @@ struct YerbaResult yerba_document_set(struct Document *document,
|
|
|
108
112
|
struct YerbaResult yerba_document_insert(struct Document *document,
|
|
109
113
|
const char *path,
|
|
110
114
|
const char *value,
|
|
115
|
+
enum YerbaValueType value_type,
|
|
111
116
|
const char *before,
|
|
112
117
|
const char *after,
|
|
113
118
|
int64_t at);
|
|
@@ -165,6 +170,13 @@ struct YerbaResult yerba_document_blank_lines(struct Document *document,
|
|
|
165
170
|
const char *path,
|
|
166
171
|
uintptr_t count);
|
|
167
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Caller must free with yerba_string_free.
|
|
175
|
+
*/
|
|
176
|
+
char *yerba_document_validate_schema(const struct Document *document,
|
|
177
|
+
const char *schema_json,
|
|
178
|
+
const char *selector);
|
|
179
|
+
|
|
168
180
|
/**
|
|
169
181
|
* Caller must free with yerba_string_free.
|
|
170
182
|
*/
|