-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoolbox.nu
62 lines (52 loc) · 1.93 KB
/
toolbox.nu
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
# toolbox.nu
# Based on: https://www.nushell.sh/cookbook/jq_v_nushell.html#appendix-custom-commands
use std assert
# Like `describe` but dropping item types for collections.
export def describe-primitive []: any -> string {
$in | describe | str replace --regex '<.*' ''
}
# A command for cherry-picking values from a record key recursively
export def "flatten record-paths" [
--separator (-s): string = "." # The separator to use when chaining paths
] {
let input = $in
if ($input | describe) !~ "record" {
error make {msg: "The record-paths command expects a record"}
}
$input | flatten-record-paths $separator
}
def flatten-record-paths [separator: string, ctx?: string] {
let input = $in
match ($input | describe-primitive) {
"record" => {
$input
| items { |key, value|
let path = if $ctx == null { $key } else { [$ctx $key] | str join $separator }
{path: $path, value: $value}
}
| reduce -f [] { |row, acc|
$acc
| append ($row.value | flatten-record-paths $separator $row.path)
| flatten
}
},
"list" => {
$input
| enumerate
| each { |e|
{path: ([$ctx $e.index] | str join $separator), value: $e.item}
}
},
"table" | "block" | "closure" => { error make {msg: "Unexpected type"} },
_ => {
{path: $ctx, value: $input}
},
}
}
#[test]
def test_record_path [] {
assert equal ({a: 1} | flatten record-paths) [{path: "a", value: 1}]
assert equal ({a: 1, b: [2 3]} | flatten record-paths) [[path value]; [a 1] ["b.0" 2] ["b.1" 3]]
assert equal ({a: 1, b: {c: 2}} | flatten record-paths) [[path value]; [a 1] ["b.c" 2]]
assert equal ({a: {b: {c: null}}} | flatten record-paths -s "->") [[path value]; ["a->b->c" null]]
}