From 0a5c82274fe7284591154aacfa1f740d1132b69e Mon Sep 17 00:00:00 2001 From: Gabin Lefranc Date: Wed, 29 Nov 2023 16:12:23 +0100 Subject: [PATCH] Add `record` module (#679) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a module to manipulate records. It can be a potential candidate to nu's standard library ? Take a look at the name of the functions to see if they respect naming convention (or if you have better ideas of course 😉 ) --- modules/README.md | 4 + stdlib-candidate/record/README.md | 121 ++++++++++++++++++++++++++++++ stdlib-candidate/record/mod.nu | 69 +++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 stdlib-candidate/record/README.md create mode 100644 stdlib-candidate/record/mod.nu diff --git a/modules/README.md b/modules/README.md index 960eccb..6ce9d56 100644 --- a/modules/README.md +++ b/modules/README.md @@ -20,6 +20,7 @@ - [nvim](#nvim) - [progress\_bar](#progress_bar) - [rbenv](#rbenv) + - [record](#record) - [system](#system) - [virtual\_environments](#virtual_environments) - [weather](#weather) @@ -168,6 +169,9 @@ It is basically a join of the tables produced by the `lsof` command, and the nus ## [rbenv](./rbenv/) ??? (not sure how universal this is) This script provides minimal working rbenv setup. +## [record](./record/) +A module to manipulate nu's record + ## [system](./system/) Currently holds the `clip` command which was previously incorrectly in the standard library of Nushell. ```nushell diff --git a/stdlib-candidate/record/README.md b/stdlib-candidate/record/README.md new file mode 100644 index 0000000..4162827 --- /dev/null +++ b/stdlib-candidate/record/README.md @@ -0,0 +1,121 @@ +# Record module + +A module to manipulate nu's records. + +## `record list merge` + +### Input/output types: + +|#|input|output| +|-|-|-| +|1|list\|record| + +### Example + +```nu +> [{a:1} {b:2} {c:3}] | record list merge +╭───┬───╮ +│ a │ 1 │ +│ b │ 2 │ +│ c │ 3 │ +╰───┴───╯ +``` + +## `record filter-name predicate` + +Filter a record by validating fields name with a predicate. + +### Input/output types: + +|#|input|output| +|-|-|-| +|1|record|record| + +## Arguments + +* `pred`: Predicate closure that checks fields name + +### Example + +```nu +> $env | record filter-name predicate { $in | str contains VS} +╭───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ VSCODE_GIT_ASKPASS_EXTRA_ARGS │ --ms-enable-electron-run-as-node │ +│ VSCODE_GIT_ASKPASS_MAIN │ /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js │ +│ VSCODE_GIT_ASKPASS_NODE │ /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) │ +│ VSCODE_GIT_IPC_HANDLE │ /var/folders/_x/25cgjd3n2sn62x6jfc9ccjjw0000gn/T/vscode-git-56538693f8.sock │ +╰───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +## `record filter-name text` + +Filter a record by validating fields name with text. + +### Input/output types: + +|#|input|output| +|-|-|-| +|1|record|record| + +## Arguments + +* `filter`: Text to match with +* `--regex(-r)`: Match by regex + +### Examples + +```nu +> $env | record filter-name text VS +╭───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ VSCODE_GIT_ASKPASS_EXTRA_ARGS │ --ms-enable-electron-run-as-node │ +│ VSCODE_GIT_ASKPASS_MAIN │ /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js │ +│ VSCODE_GIT_ASKPASS_NODE │ /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) │ +│ VSCODE_GIT_IPC_HANDLE │ /var/folders/_x/25cgjd3n2sn62x6jfc9ccjjw0000gn/T/vscode-git-56538693f8.sock │ +╰───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ + +> $env | record filter-name text --regex V.*S +╭───────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ │ ╭──────┬──────────────────────────────────╮ │ +│ ENV_CONVERSIONS │ │ │ ╭─────────────┬────────────────╮ │ │ +│ │ │ PATH │ │ from_string │ │ │ │ +│ │ │ │ │ to_string │ │ │ │ +│ │ │ │ ╰─────────────┴────────────────╯ │ │ +│ │ │ │ ╭─────────────┬────────────────╮ │ │ +│ │ │ Path │ │ from_string │ │ │ │ +│ │ │ │ │ to_string │ │ │ │ +│ │ │ │ ╰─────────────┴────────────────╯ │ │ +│ │ ╰──────┴──────────────────────────────────╯ │ +│ LC_TERMINAL_VERSION │ 3.4.22 │ +│ NU_VERSION │ 0.87.0 │ +│ PROMPT_INDICATOR_VI_INSERT │ │ +│ TERM_PROGRAM_VERSION │ 1.84.2 │ +│ VSCODE_GIT_ASKPASS_EXTRA_ARGS │ --ms-enable-electron-run-as-node │ +│ VSCODE_GIT_ASKPASS_MAIN │ /Applications/Visual Studio Code.app/Contents/Resources/app/extensions/git/dist/askpass-main.js │ +│ VSCODE_GIT_ASKPASS_NODE │ /Applications/Visual Studio Code.app/Contents/Frameworks/Code Helper (Plugin).app/Contents/MacOS/Code Helper (Plugin) │ +│ VSCODE_GIT_IPC_HANDLE │ /var/folders/_x/25cgjd3n2sn62x6jfc9ccjjw0000gn/T/vscode-git-56538693f8.sock │ +╰───────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +``` + +## `record filter-value predicate` + +Filter a record by validating fields value with predicate. + +### Input/output types: + +|#|input|output| +|-|-|-| +|1|record|record| + +## Arguments + +* `pred`: Predicate closure that checks fields value + +### Example + +```nu +> {a:1 b:2 c:3 d:4} | record filter-value predicate { $in mod 2 == 0 } +╭───┬───╮ +│ b │ 2 │ +│ d │ 4 │ +╰───┴───╯ +``` \ No newline at end of file diff --git a/stdlib-candidate/record/mod.nu b/stdlib-candidate/record/mod.nu new file mode 100644 index 0000000..f4a3db5 --- /dev/null +++ b/stdlib-candidate/record/mod.nu @@ -0,0 +1,69 @@ +# Merge a list of records +export def "list merge" []: list -> record { + let list = $in + mut result = {} + for $obj in $list { + $result = ($result | merge $obj) + } + $result +} + +# Filter fields name by predicate +export def "filter-name predicate" [ + pred: closure # Predicate closure that checks fields name +]: record -> record { + let $obj_input = $in + $obj_input + | columns + | where { $in | do $pred } + | each {|input| + { $input: ($obj_input | get $input) } + } + | list merge +} + +# Filter fields name by text checking +export def "filter-name text" [ + filter: string # Text to match with + --regex(-r) # Match by regex +]: record -> record { + let obj = $in + $obj | filter-name predicate { not ($in | (if $regex {find -r $filter} else {find $filter}) | is-empty) } +} + +# Filter fields value by predicate +export def "filter-value predicate" [ + pred: closure # Predicate closure that checks fields value +]: record -> record { + let $obj_input = $in + $obj_input + | columns + | where {|col| $obj_input | get $col | do $pred } + | each {|input| + { $input: ($obj_input | get $input) } + } + | list merge +} + +#[test] +def test_record_list_merge [] { + use std assert + assert equal ([{a:1} {b:2} {c:3} {d:4}] | list merge) {a:1 b:2 c:3 d:4} +} +#[test] +def test_record_filtername_predicate [] { + use std assert + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name predicate {$in | str contains a}) {aa:1 ab:2 ba:3 ca:5} +} +#[test] +def test_record_filtername_text [] { + use std assert + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text a) {aa:1 ab:2 ba:3 ca:5} + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text -r ^a) {aa:1 ab:2} + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-name text -r ^A) {} +} +#[test] +def test_record_filtervalue_predicate [] { + use std assert + assert equal ({aa:1 ab:2 ba:3 bb:4 ca:5 cb:6} | filter-value predicate { $in mod 2 == 0 }) {ab:2 bb:4 cb:6} +} \ No newline at end of file