ry 0.1.1

rusty yaml searching
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# ry
ry searches yaml for matching paths/values. It's written in rust and inspired by [yq](https://github.com/mikefarah/yq)

---

## Usage

`ry <yaml_file_name> <path_expression>`

Returns the nodes in `yaml_file_name` matching `path_expression`. See [**Basic**](https://github.com/willdeuschle/ry#basic) for `path_expression` examples.

## Basic

For a file `test_map.yml` containing:
```
a:
  b: 1
```
then:
```
ry test_map.yml 'a.b'
```
will return `1`.

And for a file `test_array.yml` containing:
```
letters:
  - a
  - b
```
then:
```
ry test_array.yml 'letters[1]'
```
will return `b`. 

---

### From STDIN

For the `test_map.yml` file above, the following:
```
cat test.yml | target/release/ry - 'a.b'
```
will return `1`. Note that the `-` character represents `STDIN`.

### Wildcard matching

The `'*'` character acts as a wildcard in path expressions. For a file `test_wild.yml` containing:
```
a:
  item_b:
    f: 1
  thing_c:
    f: 2
  item_d:
    f: 3
```
then:
```
ry test_wild.yml 'a.*.f'
```
will return:
```
1
2
3
```

You can also use wildcards with a prefix, for example:
```
ry test_wild.yml 'a.item*.f'
```
will return:
```
1
3
```

Finally, wildcards can be used to match array elements as well. For the file `test_wild_array.yml` containing:
```
letters:
  - a
  - b
  - c
```
then:
```
ry test_wild_array.yml 'letters[*]'
```
will return:
```
a
b
c
```

### Deep splat matching

The deep splat pattern `'**'` is used to recursively match nodes in a file. For the file `test_splat.yml` containing:
```
a:
  b1:
    c: # MATCH
      c: crabs_1 # MATCH
    d: bears
  b2:
    c: crabs_2
    d: bears
  b3:
    e:
      - f:
          c: crabs_3 # MATCH
          g: bears
      - f:
          g:
            c: crabs_4 # MATCH
            h: bears
      - f: bears
```
then:
```
ry test_splat.yml 'a.**.c'
```
will return:
```
crabs_1
c: crabs_1
crabs_2
crabs_3
crabs_4
```

### Printing matching paths

The `--printMode` feature flag allows you to print the paths leading to matching nodes. For a file `test_wild.yml` containing:
```
a:
  item_b:
    f: 1
  thing_c:
    f: 2
  item_d:
    f: 3
```
then:
```
ry test_wild.yml 'a.*.f' --printMode p
```
will return:
```
a.item_b.f
a.thing_c.f
a.item_d.f
```
while:
```
ry test_wild.yml 'a.*.f' --printMode pv
```
will return both matching paths and values:
```
a.item_b.f: 1
a.thing_c.f: 2
a.item_d.f: 3
```
Note that:
```
ry test_wild.yml a.*.f --printMode v
```
is equivalent to the default:
```
ry test_wild.yml 'a.*.f'
```
which will just return matching values:
```
1
2
3
```

### Multi-doc support
If you have multiple documents in a single yaml file, the `-d` feature flag allows you to apply your search to a specific document. By default all documents are searched.

For the file `test_multi_doc.yml` containing:
```
a:
  b: 1
crabs: here
---
a:
  b: 2
```
then:
```
ry test_multi_doc.yml 'a.b' -d1
```
will return `2`, while:
```
ry test_multi_doc.yml 'a.b' -d0
```
will return `1`. Finally:
```
ry test_multi_doc.yml 'a.b' -d'*'
```
will return:
```
1
2
```

### Collecting results into an array
The feature flag `--collect` will collect the output elements into an array. For the file `test_collect.yml` containing:
```
letters:
  a:
    crab: 1
  b:
    crab: 2
  c:
    crab: 3
```
then:
```
ry test_collect.yml 'letters.*.crab'
```
will return:
```
1
2
3
```
while:
```
ry test_collect.yml 'letters.*.crab' --collect
```
will return:
```
- 1
- 2
- 3
```

### Printing the length of results
The `--length` feature flag prints the length of results.

For arrays, length means the number of items. For the file `test_array_length.yml` containing:
```
looking:
  - here
  - there
  - elsewhere
```
then:
```
ry test_array_length.yml 'looking' --length
```
will return `3`.

For maps, length means the number of entries. For the file `test_map_length.yml` containing:
```
looking:
  here: yes
  there: yes
  elsewhere: no
```
then:
```
ry test_map_length.yml 'looking' --length
```
will return `3`.

Finally for scalars, length means the length of the scalar. For the file `test_string_length.yml` containing:
```
looking: string
```
then:
```
ry test_string_length.yml 'looking' --length
```
will return `6`. For the file `test_int_length.yml` containing:
```
looking: 100
```
then:
```
ry test_int_length.yml 'looking' --length
```
will return `3`.

### Anchors and Aliases
Anchors and aliases will be substituted automatically. This means that for a file `anchor_and_alias.yml` containing:
```
first: &crab
  a: b
second: *crab
```
then:
```
ry anchor_and_alias.yml 'second.a'
```
will return `b`.

## Advanced

### Filtering by children nodes
You can filter parent nodes based on their children. For the file `test_filter.yml` containing:
```
a:
  - b:
      c: magic
    d: crab
  - b:
      c: magically
    d: bear
  - b:
      c: magic
    d: more crab
  - b:
      careful: magic
    d: most crab
```
then
```
ry test_filter.yml 'a.(b.c==magic).d' --printMode pv
```
will return:
```
a[0].d: crab
a[2].d: more crab
```
> Note that `(b.c==magic)` filters based on the children of each array member under `a`, but it returns the parents of those children for further searching (i.e. the filter `(b.c==magic)` returns array members under `a`).

Filtering also supports wildcards, for example:
```
ry test_filter.yml 'a.(b.c*==magic*).d' --printMode pv
```
will return:
```
a[0].d: crab
a[1].d: bear
a[2].d: more crab
a[3].d: most crab
```

### Matching on children values
Similar filtering by children nodes, it's also possible to filter based on children values.

For arrays, this just means matching the value in the array. For the file `matching_array.yml` containing:
```
crabs:
  - abby
  - carl
  - alexandra
```
then:
```
ry matching_array.yml 'crabs(.==a*)' --printMode pv
```
will return:
```
crabs[0]: abby
crabs[2]: alexandra
```

For maps, this just means matching the map entry's value. For the file `matching_map.yml` containing:
```
crabs:
  name_1: abby
  name_2: carl
  name_3: alexandra
```
then:
```
ry matching_map.yml 'crabs(.==a*)' --printMode pv
```
will return:
```
crabs.name_1: abby
crabs.name_3: alexandra
```
Notice that this ignores the keys of the map entries.

### Length of filtered results
The length of filtered results get printed individually. For the file `test_filtered_length.yml` containing:
```
crabs:
  - abby
  - carl
  - alexandra
```
then:
```
ry test_filtered_length.yml 'crabs(.==a*)' --printMode pv --length
```
will return:
```
crabs[0]: 4
crabs[2]: 9
```

However, if you want to know the total number of filtered results, you can use the `--collect` and `--length` feature flags together. Then:
```
ry test_filtered_length.yml 'crabs(.==a*)' --length --collect
```
will return `2`.