mirror of
https://github.com/nushell/nushell.git
synced 2025-07-01 07:00:37 +02:00
Compare commits
65 Commits
Author | SHA1 | Date | |
---|---|---|---|
d1c719a8cc | |||
4d854f36af | |||
8d5848c955 | |||
fe88d58b1e | |||
42dbfd1fa0 | |||
534e1fc3ce | |||
ff946a2f21 | |||
3c0cbec993 | |||
48e29e9ed6 | |||
ff53352afe | |||
4fd4136d50 | |||
dc1248a454 | |||
de554f8e5f | |||
44979f3051 | |||
7ae7394c85 | |||
9dbf7556b8 | |||
caafd26deb | |||
43a218240c | |||
11d7d8ea1e | |||
2dea9e6f1f | |||
c5cb369d8d | |||
b6959197bf | |||
d5b99ae316 | |||
9d10007085 | |||
2e0b964d5b | |||
5bae7e56ef | |||
b42ef45c7c | |||
3423cd54a1 | |||
837f0463eb | |||
56f6f683fc | |||
c57f41e5f2 | |||
8c74b1e437 | |||
8318d59ef1 | |||
64efa30f3e | |||
820a6bfb08 | |||
b8d253cbd7 | |||
3c421c5726 | |||
75b2d26187 | |||
17a5aa3052 | |||
e4a22799d5 | |||
fda456e469 | |||
e5d38dcff6 | |||
a82fa75c31 | |||
0c16464320 | |||
888758b813 | |||
cb909f810e | |||
a75318d7e8 | |||
7a9bf06005 | |||
a06299c77a | |||
e4bcd1934d | |||
4673adecc5 | |||
1b8051ece5 | |||
d44059c36b | |||
b79abdb2a5 | |||
ee8a0c9477 | |||
41853b9f18 | |||
997d56a288 | |||
0769e9b750 | |||
f5519e2a09 | |||
8259d463aa | |||
e2c015f725 | |||
eb12fffbc6 | |||
c42096c34e | |||
46eb34b35d | |||
23a73cd31f |
@ -1,6 +1,7 @@
|
||||
# increase the default windows stack size
|
||||
[target.x86_64-pc-windows-msvc]
|
||||
rustflags = ["-C", "link-args=-stack:10000000"]
|
||||
# increase the default windows stack size
|
||||
# statically link the CRT so users don't have to install it
|
||||
rustflags = ["-C", "link-args=-stack:10000000", "-C", "target-feature=+crt-static"]
|
||||
|
||||
# keeping this but commentting out in case we need them in the future
|
||||
|
||||
|
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -80,9 +80,11 @@ jobs:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
with:
|
||||
key: ${{ matrix.style }}v3 # increment this to bust the cache if needed
|
||||
# Temporarily disabled; the cache was getting huge (2.6GB compressed) on Windows and causing issues.
|
||||
# TODO: investigate why the cache was so big
|
||||
# - uses: Swatinem/rust-cache@v1
|
||||
# with:
|
||||
# key: ${{ matrix.style }}v3 # increment this to bust the cache if needed
|
||||
|
||||
- name: Tests
|
||||
uses: actions-rs/cargo@v1
|
||||
|
@ -1,21 +1,14 @@
|
||||
# Contributing
|
||||
|
||||
Welcome to nushell!
|
||||
|
||||
*Note: for a more complete guide see [The nu contributor book](https://www.nushell.sh/contributor-book/)*
|
||||
|
||||
For speedy contributions open it in Gitpod, nu will be pre-installed with the latest build in a VSCode like editor all from your browser.
|
||||
|
||||
[](https://gitpod.io/#https://github.com/nushell/nushell)
|
||||
Welcome to Nushell!
|
||||
|
||||
To get live support from the community see our [Discord](https://discordapp.com/invite/NtAbbGn), [Twitter](https://twitter.com/nu_shell) or file an issue or feature request here on [GitHub](https://github.com/nushell/nushell/issues/new/choose)!
|
||||
<!--WIP-->
|
||||
|
||||
## Developing
|
||||
|
||||
### Set up
|
||||
### Setup
|
||||
|
||||
This is no different than other Rust projects.
|
||||
Nushell requires a recent Rust toolchain and some dependencies; [refer to the Nu Book for up-to-date requirements](https://www.nushell.sh/book/installation.html#build-from-source). After installing dependencies, you should be able to clone+build Nu like any other Rust project:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/nushell/nushell
|
||||
@ -28,24 +21,24 @@ cargo build
|
||||
- Build and run Nushell:
|
||||
|
||||
```shell
|
||||
cargo build --release && cargo run --release
|
||||
cargo run
|
||||
```
|
||||
|
||||
- Build and run with extra features:
|
||||
- Build and run with extra features. Currently extra features include dataframes and sqlite database support.
|
||||
```shell
|
||||
cargo build --release --features=extra && cargo run --release --features=extra
|
||||
cargo run --features=extra
|
||||
```
|
||||
|
||||
- Run Clippy on Nushell:
|
||||
|
||||
```shell
|
||||
cargo clippy --all --features=stable
|
||||
cargo clippy --workspace --features=extra -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect
|
||||
```
|
||||
|
||||
- Run all tests:
|
||||
|
||||
```shell
|
||||
cargo test --all --features=stable
|
||||
cargo test --workspace --features=extra
|
||||
```
|
||||
|
||||
- Run all tests for a specific command
|
||||
@ -71,5 +64,5 @@ cargo build
|
||||
- To view verbose logs when developing, enable the `trace` log level.
|
||||
|
||||
```shell
|
||||
cargo build --release --features=extra && cargo run --release --features=extra -- --log-level trace
|
||||
cargo run --release --features=extra -- --log-level trace
|
||||
```
|
||||
|
201
Cargo.lock
generated
201
Cargo.lock
generated
@ -215,9 +215,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.53"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed6aa3524a2dfcf9fe180c51eae2b58738348d819517ceadf95789c51fff7600"
|
||||
checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -375,9 +375,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
version = "3.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
|
||||
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
|
||||
|
||||
[[package]]
|
||||
name = "byte-unit"
|
||||
@ -561,9 +561,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.23"
|
||||
version = "0.2.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0936ffe6d0c8d6a51b3b0a73b2acbe925d786f346cf45bfddc8341d79fb7dc8a"
|
||||
checksum = "e6a1316fa6a23fea1ee41cb80321590385e5f3e575e99f77c4d918ce5d44379d"
|
||||
dependencies = [
|
||||
"const_format_proc_macros",
|
||||
]
|
||||
@ -603,9 +603,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cortex-m"
|
||||
version = "0.7.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37ff967e867ca14eba0c34ac25cd71ea98c678e741e3915d923999bb2fe7c826"
|
||||
checksum = "cd20d4ac4aa86f4f75f239d59e542ef67de87cce2c282818dc6e84155d3ea126"
|
||||
dependencies = [
|
||||
"bare-metal 0.2.5",
|
||||
"bitfield",
|
||||
@ -698,7 +698,7 @@ dependencies = [
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio 0.8.3",
|
||||
"parking_lot 0.12.0",
|
||||
"parking_lot 0.12.1",
|
||||
"serde",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
@ -1128,13 +1128,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.23"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
|
||||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
@ -1361,6 +1359,16 @@ dependencies = [
|
||||
"version_check 0.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.21"
|
||||
@ -1649,9 +1657,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.18"
|
||||
version = "0.14.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b26ae0a80afebe130861d90abf98e3814a4f28a4c6ffeb5ab8ebb2be311e0ef2"
|
||||
checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
@ -1712,9 +1720,9 @@ checksum = "0cfe9645a18782869361d9c8732246be7b410ad4e919d3609ebabdac00ba12c3"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.8.1"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
|
||||
checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.11.2",
|
||||
@ -1791,6 +1799,16 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
|
||||
|
||||
[[package]]
|
||||
name = "is-root"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04a4202a60e86f1c9702706bb42270dadd333f2db7810157563c86f17af3c873"
|
||||
dependencies = [
|
||||
"users 0.10.0",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
version = "1.1.1"
|
||||
@ -1914,9 +1932,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-integer"
|
||||
version = "0.8.5"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "125e1f93e5003d4bd89758c2ca2771bfae13632df633cde581efe07c87d354e5"
|
||||
checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9"
|
||||
dependencies = [
|
||||
"lexical-util",
|
||||
"static_assertions",
|
||||
@ -2015,9 +2033,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.6"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e7e15d7610cce1d9752e137625f14e61a28cd45929b6e12e47b50fe154ee2e"
|
||||
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@ -2142,9 +2160,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.3"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f"
|
||||
checksum = "d5172b50c23043ff43dd53e51392f36519d9b35a8f3a410d30ece5d1aedd58ae"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
@ -2235,9 +2253,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.1"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
|
||||
checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
@ -2452,7 +2470,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"assert_cmd",
|
||||
"chrono",
|
||||
@ -2486,15 +2504,16 @@ dependencies = [
|
||||
"reedline",
|
||||
"rstest",
|
||||
"serial_test",
|
||||
"signal-hook",
|
||||
"tempfile",
|
||||
"winres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.45.1"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7bca0d33a384280d1563b97f49cb95303df9fa22588739a04b7d8015c1ccd50"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi 0.3.9",
|
||||
@ -2502,8 +2521,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-cli"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossterm",
|
||||
"fuzzy-matcher",
|
||||
"is_executable",
|
||||
@ -2519,12 +2539,13 @@ dependencies = [
|
||||
"nu-test-support",
|
||||
"nu-utils",
|
||||
"reedline",
|
||||
"sysinfo 0.24.1",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-color-config"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"nu-ansi-term",
|
||||
"nu-json",
|
||||
@ -2535,7 +2556,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-command"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"alphanumeric-sort",
|
||||
@ -2560,6 +2581,7 @@ dependencies = [
|
||||
"htmlescape",
|
||||
"ical",
|
||||
"indexmap",
|
||||
"is-root",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@ -2605,7 +2627,7 @@ dependencies = [
|
||||
"shadow-rs",
|
||||
"sqlparser",
|
||||
"strip-ansi-escapes",
|
||||
"sysinfo",
|
||||
"sysinfo 0.23.13",
|
||||
"terminal_size",
|
||||
"thiserror",
|
||||
"titlecase",
|
||||
@ -2614,27 +2636,28 @@ dependencies = [
|
||||
"umask",
|
||||
"unicode-segmentation",
|
||||
"url",
|
||||
"users",
|
||||
"users 0.11.0",
|
||||
"uuid",
|
||||
"wax",
|
||||
"which",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-engine"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"nu-glob",
|
||||
"nu-path",
|
||||
"nu-protocol",
|
||||
"nu-utils",
|
||||
"sysinfo",
|
||||
"sysinfo 0.23.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-glob"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"doc-comment",
|
||||
"tempdir",
|
||||
@ -2642,7 +2665,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-json"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
@ -2655,7 +2678,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-parser"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"log",
|
||||
@ -2669,7 +2692,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-path"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"dunce",
|
||||
@ -2678,7 +2701,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-plugin"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"capnp",
|
||||
"nu-engine",
|
||||
@ -2689,7 +2712,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-pretty-hex"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"heapless 0.7.13",
|
||||
"nu-ansi-term",
|
||||
@ -2698,7 +2721,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-protocol"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"byte-unit",
|
||||
"chrono",
|
||||
@ -2718,7 +2741,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-system"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"errno",
|
||||
@ -2732,7 +2755,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-table"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"ansi-str",
|
||||
"atty",
|
||||
@ -2745,7 +2768,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-term-grid"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"strip-ansi-escapes",
|
||||
"unicode-width",
|
||||
@ -2753,7 +2776,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-test-support"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"getset",
|
||||
"hamcrest2",
|
||||
@ -2765,14 +2788,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-utils"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"crossterm_winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_example"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"nu-plugin",
|
||||
"nu-protocol",
|
||||
@ -2780,7 +2803,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_gstat"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"git2",
|
||||
"nu-engine",
|
||||
@ -2790,7 +2813,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_inc"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"nu-plugin",
|
||||
"nu-protocol",
|
||||
@ -2799,7 +2822,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu_plugin_query"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
dependencies = [
|
||||
"gjson",
|
||||
"nu-engine",
|
||||
@ -3028,9 +3051,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.73"
|
||||
version = "0.9.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0"
|
||||
checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
@ -3074,9 +3097,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core 0.9.3",
|
||||
@ -3381,7 +3404,7 @@ checksum = "eedc21001f05611e41bb7439b38d0f4ef9406aa49c17f3b289b5f57d8fa40c59"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"glob",
|
||||
"parking_lot 0.12.0",
|
||||
"parking_lot 0.12.1",
|
||||
"polars-arrow",
|
||||
"polars-core",
|
||||
"polars-io",
|
||||
@ -3419,7 +3442,7 @@ version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7f4cd569d383f5f000abbd6d5146550e6cb4e43fac30d1af98699499a440d56"
|
||||
dependencies = [
|
||||
"parking_lot 0.12.0",
|
||||
"parking_lot 0.12.1",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
@ -3793,17 +3816,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "reedline"
|
||||
version = "0.6.0"
|
||||
source = "git+https://github.com/nushell/reedline?branch=main#fe795caabc5401d811006b93d5a6d4f220a049ff"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f8163ab90fabf0b8978b824743bb7a384394501b4b40c198a146c0eb9670ca4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossterm",
|
||||
"fd-lock",
|
||||
"gethostname",
|
||||
"nu-ansi-term",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strip-ansi-escapes",
|
||||
"strum 0.24.0",
|
||||
"strum_macros 0.24.0",
|
||||
"thiserror",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
@ -4012,9 +4040,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.34.7"
|
||||
version = "0.34.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f117495127afb702af6706f879fb2b5c008c38ccf3656afc514e26f35bdb8180"
|
||||
checksum = "2079c267b8394eb529872c3cf92e181c378b41fea36e68130357b52493701d2e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
@ -4438,7 +4466,7 @@ checksum = "213494b7a2b503146286049378ce02b482200519accc31872ee8be91fa820a08"
|
||||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
"parking_lot 0.12.1",
|
||||
"phf_shared 0.10.0",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
@ -4554,9 +4582,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.95"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942"
|
||||
checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -4603,6 +4631,21 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6a8e71535da31837213ac114531d31def75d7aebd133264e420a3451fa7f703"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"ntapi",
|
||||
"once_cell",
|
||||
"rayon",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempdir"
|
||||
version = "0.3.7"
|
||||
@ -4747,9 +4790,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.18.2"
|
||||
version = "1.19.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4903bf0427cf68dddd5aa6a93220756f8be0c34fcfa9f5e6191e103e15a31395"
|
||||
checksum = "c51a52ed6686dd62c320f9b89299e9dfb46f730c7a48e635c19f21d116cb1439"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
@ -4774,9 +4817,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f988a1a1adc2fb21f9c12aa96441da33a1728193ae0b95d2be22dbd17fcb4e5c"
|
||||
checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@ -4809,21 +4852,9 @@ checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.26"
|
||||
@ -4972,6 +5003,16 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa4227e95324a443c9fcb06e03d4d85e91aabe9a5a02aa818688b6918b6af486"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "users"
|
||||
version = "0.11.0"
|
||||
|
39
Cargo.toml
39
Cargo.toml
@ -11,7 +11,7 @@ name = "nu"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/nushell/nushell"
|
||||
rust-version = "1.60"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -32,37 +32,38 @@ members = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.19"
|
||||
chrono = { version = "0.4.19", features = ["serde"] }
|
||||
crossterm = "0.23.0"
|
||||
ctrlc = "3.2.1"
|
||||
log = "0.4"
|
||||
miette = "4.5.0"
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-cli = { path="./crates/nu-cli", version = "0.63.1" }
|
||||
nu-color-config = { path = "./crates/nu-color-config", version = "0.63.1" }
|
||||
nu-command = { path="./crates/nu-command", version = "0.63.1" }
|
||||
nu-engine = { path="./crates/nu-engine", version = "0.63.1" }
|
||||
nu-json = { path="./crates/nu-json", version = "0.63.1" }
|
||||
nu-parser = { path="./crates/nu-parser", version = "0.63.1" }
|
||||
nu-path = { path="./crates/nu-path", version = "0.63.1" }
|
||||
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.63.1" }
|
||||
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.63.1" }
|
||||
nu-protocol = { path = "./crates/nu-protocol", version = "0.63.1" }
|
||||
nu-system = { path = "./crates/nu-system", version = "0.63.1" }
|
||||
nu-table = { path = "./crates/nu-table", version = "0.63.1" }
|
||||
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.63.1" }
|
||||
nu-utils = { path = "./crates/nu-utils", version = "0.63.1" }
|
||||
nu-ansi-term = "0.46.0"
|
||||
nu-cli = { path="./crates/nu-cli", version = "0.64.0" }
|
||||
nu-color-config = { path = "./crates/nu-color-config", version = "0.64.0" }
|
||||
nu-command = { path="./crates/nu-command", version = "0.64.0" }
|
||||
nu-engine = { path="./crates/nu-engine", version = "0.64.0" }
|
||||
nu-json = { path="./crates/nu-json", version = "0.64.0" }
|
||||
nu-parser = { path="./crates/nu-parser", version = "0.64.0" }
|
||||
nu-path = { path="./crates/nu-path", version = "0.64.0" }
|
||||
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.64.0" }
|
||||
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.64.0" }
|
||||
nu-protocol = { path = "./crates/nu-protocol", version = "0.64.0" }
|
||||
nu-system = { path = "./crates/nu-system", version = "0.64.0" }
|
||||
nu-table = { path = "./crates/nu-table", version = "0.64.0" }
|
||||
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.64.0" }
|
||||
nu-utils = { path = "./crates/nu-utils", version = "0.64.0" }
|
||||
reedline = { version = "0.7.0", features = ["bashisms", "sqlite"]}
|
||||
pretty_env_logger = "0.4.0"
|
||||
rayon = "1.5.1"
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
is_executable = "1.0.1"
|
||||
|
||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||
# Our dependencies don't use OpenSSL on Windows
|
||||
openssl = { version = "0.10.38", features = ["vendored"], optional = true }
|
||||
signal-hook = { version = "0.3.14", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { path="./crates/nu-test-support", version = "0.63.1" }
|
||||
nu-test-support = { path="./crates/nu-test-support", version = "0.64.0" }
|
||||
tempfile = "3.2.0"
|
||||
assert_cmd = "2.0.2"
|
||||
pretty_assertions = "1.0.0"
|
||||
|
249
README.md
249
README.md
@ -1,5 +1,4 @@
|
||||
# README
|
||||
|
||||
# Nushell <!-- omit in toc -->
|
||||
[](https://crates.io/crates/nu)
|
||||

|
||||
[](https://discord.gg/NtAbbGn)
|
||||
@ -8,128 +7,100 @@
|
||||

|
||||

|
||||
|
||||
## Nushell
|
||||
|
||||
A new type of shell.
|
||||
|
||||

|
||||
|
||||
## Table of Contents <!-- omit in toc -->
|
||||
|
||||
- [Status](#status)
|
||||
- [Learning About Nu](#learning-about-nu)
|
||||
- [Installation](#installation)
|
||||
- [Philosophy](#philosophy)
|
||||
- [Pipelines](#pipelines)
|
||||
- [Opening files](#opening-files)
|
||||
- [Plugins](#plugins)
|
||||
- [Goals](#goals)
|
||||
- [Progress](#progress)
|
||||
- [Officially Supported By](#officially-supported-by)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
|
||||
## Status
|
||||
|
||||
This project has reached a minimum-viable product level of quality.
|
||||
While contributors dogfood it as their daily driver, it may be unstable for some commands.
|
||||
Future releases will work to fill out missing features and improve stability.
|
||||
Its design is also subject to change as it matures.
|
||||
This project has reached a minimum-viable-product level of quality. Many people use it as their daily driver, but it may be unstable for some commands. Nu's design is subject to change as it matures.
|
||||
|
||||
Nu comes with a set of built-in commands (listed below).
|
||||
If a command is unknown, the command will shell-out and execute it (using cmd on Windows or bash on Linux and macOS), correctly passing through stdin, stdout, and stderr, so things like your daily git workflows and even `vim` will work just fine.
|
||||
## Learning About Nu
|
||||
|
||||
## Learning more
|
||||
The [Nushell book](https://www.nushell.sh/book/) is the primary source of Nushell documentation. You can find [a full list of Nu commands in the book](https://www.nushell.sh/book/command_reference.html), and we have many examples of using Nu in our [cookbook](https://www.nushell.sh/cookbook/).
|
||||
|
||||
There are a few good resources to learn about Nu.
|
||||
There is a [book](https://www.nushell.sh/book/) about Nu that is currently in progress.
|
||||
The book focuses on using Nu and its core concepts.
|
||||
|
||||
If you're a developer who would like to contribute to Nu, we're also working on a [book for developers](https://www.nushell.sh/contributor-book/) to help you get started.
|
||||
There are also [good first issues](https://github.com/nushell/nushell/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) to help you dive in.
|
||||
|
||||
We also have an active [Discord](https://discord.gg/NtAbbGn) and [Twitter](https://twitter.com/nu_shell) if you'd like to come and chat with us.
|
||||
|
||||
You can also find information on more specific topics in our [cookbook](https://www.nushell.sh/cookbook/).
|
||||
We're also active on [Discord](https://discord.gg/NtAbbGn) and [Twitter](https://twitter.com/nu_shell); come and chat with us!
|
||||
|
||||
## Installation
|
||||
|
||||
### Local
|
||||
To quickly install Nu:
|
||||
|
||||
Up-to-date installation instructions can be found in the [installation chapter of the book](https://www.nushell.sh/book/installation.html). **Windows users**: please note that Nu works on Windows 10 and does not currently have Windows 7/8.1 support.
|
||||
|
||||
To build Nu, you will need to use the **latest stable (1.60 or later)** version of the compiler.
|
||||
|
||||
Required dependencies:
|
||||
|
||||
- pkg-config and libssl (only needed on Linux)
|
||||
- On Debian/Ubuntu: `apt install pkg-config libssl-dev`
|
||||
|
||||
Optional dependencies:
|
||||
|
||||
- To use Nu with all possible optional features enabled, you'll also need the following:
|
||||
- On Linux (on Debian/Ubuntu): `apt install libxcb-composite0-dev libx11-dev`
|
||||
|
||||
To install Nu via cargo (make sure you have installed [rustup](https://rustup.rs/) and the latest stable compiler via `rustup install stable`):
|
||||
|
||||
For Windows users, you may also need to install the [Microsoft Visual C++ 2015 Redistributables](https://docs.microsoft.com/cpp/windows/latest-supported-vc-redist).
|
||||
|
||||
```shell
|
||||
cargo install nu
|
||||
```
|
||||
|
||||
To install Nu via the [Windows Package Manager](https://aka.ms/winget-cli):
|
||||
|
||||
```shell
|
||||
```bash
|
||||
# Linux and macOS
|
||||
brew install nushell
|
||||
# Windows
|
||||
winget install nushell
|
||||
```
|
||||
|
||||
To install Nu via the [Chocolatey](https://chocolatey.org) package manager:
|
||||
To use `Nu` in Github Action, check [setup-nu](https://github.com/marketplace/actions/setup-nu) for more detail.
|
||||
|
||||
```shell
|
||||
choco install nushell
|
||||
```
|
||||
|
||||
You can also build Nu yourself with all the bells and whistles (be sure to have installed the [dependencies](https://www.nushell.sh/book/installation.html#dependencies) for your platform), once you have checked out this repo with git:
|
||||
|
||||
```shell
|
||||
cargo build --workspace --features=extra
|
||||
```
|
||||
### Packaging status
|
||||
Detailed installation instructions can be found in the [installation chapter of the book](https://www.nushell.sh/book/installation.html). Nu is available via many package managers:
|
||||
|
||||
[](https://repology.org/project/nushell/versions)
|
||||
|
||||
#### Fedora
|
||||
|
||||
[COPR repo](https://copr.fedorainfracloud.org/coprs/atim/nushell/): `sudo dnf copr enable atim/nushell -y && sudo dnf install nushell -y`
|
||||
|
||||
## Philosophy
|
||||
|
||||
Nu draws inspiration from projects like PowerShell, functional programming languages, and modern CLI tools.
|
||||
Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure.
|
||||
For example, when you list the contents of a directory, what you get back is a table of rows, where each row represents an item in that directory.
|
||||
Rather than thinking of files and data as raw streams of text, Nu looks at each input as something with structure.
|
||||
For example, when you list the contents of a directory what you get back is a table of rows, where each row represents an item in that directory.
|
||||
These values can be piped through a series of steps, in a series of commands called a 'pipeline'.
|
||||
|
||||
### Pipelines
|
||||
|
||||
In Unix, it's common to pipe between commands to split up a sophisticated command over multiple steps.
|
||||
Nu takes this a step further and builds heavily on the idea of _pipelines_.
|
||||
Just as the Unix philosophy, Nu allows commands to output to stdout and read from stdin.
|
||||
As in the Unix philosophy, Nu allows commands to output to stdout and read from stdin.
|
||||
Additionally, commands can output structured data (you can think of this as a third kind of stream).
|
||||
Commands that work in the pipeline fit into one of three categories:
|
||||
|
||||
- Commands that produce a stream (e.g., `ls`)
|
||||
- Commands that filter a stream (eg, `where type == "Dir"`)
|
||||
- Commands that consume the output of the pipeline (e.g., `autoview`)
|
||||
- Commands that filter a stream (eg, `where type == "dir"`)
|
||||
- Commands that consume the output of the pipeline (e.g., `table`)
|
||||
|
||||
Commands are separated by the pipe symbol (`|`) to denote a pipeline flowing left to right.
|
||||
|
||||
```shell
|
||||
> ls | where type == "Dir" | autoview
|
||||
───┬────────┬──────┬───────┬──────────────
|
||||
# │ name │ type │ size │ modified
|
||||
───┼────────┼──────┼───────┼──────────────
|
||||
0 │ assets │ Dir │ 128 B │ 5 months ago
|
||||
1 │ crates │ Dir │ 704 B │ 50 mins ago
|
||||
2 │ debian │ Dir │ 352 B │ 5 months ago
|
||||
3 │ docs │ Dir │ 192 B │ 50 mins ago
|
||||
4 │ images │ Dir │ 160 B │ 5 months ago
|
||||
5 │ src │ Dir │ 128 B │ 1 day ago
|
||||
6 │ target │ Dir │ 160 B │ 5 days ago
|
||||
7 │ tests │ Dir │ 192 B │ 3 months ago
|
||||
───┴────────┴──────┴───────┴──────────────
|
||||
> ls | where type == "dir" | table
|
||||
╭────┬──────────┬──────┬─────────┬───────────────╮
|
||||
│ # │ name │ type │ size │ modified │
|
||||
├────┼──────────┼──────┼─────────┼───────────────┤
|
||||
│ 0 │ .cargo │ dir │ 0 B │ 9 minutes ago │
|
||||
│ 1 │ assets │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 2 │ crates │ dir │ 4.0 KiB │ 2 weeks ago │
|
||||
│ 3 │ docker │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 4 │ docs │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 5 │ images │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 6 │ pkg_mgrs │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 7 │ samples │ dir │ 0 B │ 2 weeks ago │
|
||||
│ 8 │ src │ dir │ 4.0 KiB │ 2 weeks ago │
|
||||
│ 9 │ target │ dir │ 0 B │ a day ago │
|
||||
│ 10 │ tests │ dir │ 4.0 KiB │ 2 weeks ago │
|
||||
│ 11 │ wix │ dir │ 0 B │ 2 weeks ago │
|
||||
╰────┴──────────┴──────┴─────────┴───────────────╯
|
||||
```
|
||||
|
||||
Because most of the time you'll want to see the output of a pipeline, `autoview` is assumed.
|
||||
Because most of the time you'll want to see the output of a pipeline, `table` is assumed.
|
||||
We could have also written the above:
|
||||
|
||||
```shell
|
||||
> ls | where type == Dir
|
||||
> ls | where type == "dir"
|
||||
```
|
||||
|
||||
Being able to use the same commands and compose them differently is an important philosophy in Nu.
|
||||
@ -137,15 +108,13 @@ For example, we could use the built-in `ps` command to get a list of the running
|
||||
|
||||
```shell
|
||||
> ps | where cpu > 0
|
||||
───┬────────┬───────────────────┬──────────┬─────────┬──────────┬──────────
|
||||
# │ pid │ name │ status │ cpu │ mem │ virtual
|
||||
───┼────────┼───────────────────┼──────────┼─────────┼──────────┼──────────
|
||||
0 │ 435 │ irq/142-SYNA327 │ Sleeping │ 7.5699 │ 0 B │ 0 B
|
||||
1 │ 1609 │ pulseaudio │ Sleeping │ 6.5605 │ 10.6 MB │ 2.3 GB
|
||||
2 │ 1625 │ gnome-shell │ Sleeping │ 6.5684 │ 639.6 MB │ 7.3 GB
|
||||
3 │ 2202 │ Web Content │ Sleeping │ 6.8157 │ 320.8 MB │ 3.0 GB
|
||||
4 │ 328788 │ nu_plugin_core_ps │ Sleeping │ 92.5750 │ 5.9 MB │ 633.2 MB
|
||||
───┴────────┴───────────────────┴──────────┴─────────┴──────────┴──────────
|
||||
╭───┬───────┬───────────┬───────┬───────────┬───────────╮
|
||||
│ # │ pid │ name │ cpu │ mem │ virtual │
|
||||
├───┼───────┼───────────┼───────┼───────────┼───────────┤
|
||||
│ 0 │ 2240 │ Slack.exe │ 16.40 │ 178.3 MiB │ 232.6 MiB │
|
||||
│ 1 │ 16948 │ Slack.exe │ 16.32 │ 205.0 MiB │ 197.9 MiB │
|
||||
│ 2 │ 17700 │ nu.exe │ 3.77 │ 26.1 MiB │ 8.8 MiB │
|
||||
╰───┴───────┴───────────┴───────┴───────────┴───────────╯
|
||||
```
|
||||
|
||||
### Opening files
|
||||
@ -155,72 +124,49 @@ For example, you can load a .toml file as structured data and explore it:
|
||||
|
||||
```shell
|
||||
> open Cargo.toml
|
||||
────────────────────┬───────────────────────────
|
||||
bin │ [table 18 rows]
|
||||
build-dependencies │ [row serde toml]
|
||||
dependencies │ [row 29 columns]
|
||||
dev-dependencies │ [row nu-test-support]
|
||||
features │ [row 19 columns]
|
||||
package │ [row 12 columns]
|
||||
workspace │ [row members]
|
||||
────────────────────┴───────────────────────────
|
||||
╭──────────────────┬────────────────────╮
|
||||
│ bin │ [table 1 row] │
|
||||
│ dependencies │ {record 24 fields} │
|
||||
│ dev-dependencies │ {record 8 fields} │
|
||||
│ features │ {record 10 fields} │
|
||||
│ package │ {record 13 fields} │
|
||||
│ profile │ {record 3 fields} │
|
||||
│ target │ {record 2 fields} │
|
||||
│ workspace │ {record 1 field} │
|
||||
╰──────────────────┴────────────────────╯
|
||||
```
|
||||
|
||||
We can pipeline this into a command that gets the contents of one of the columns:
|
||||
We can pipe this into a command that gets the contents of one of the columns:
|
||||
|
||||
```shell
|
||||
> open Cargo.toml | get package
|
||||
───────────────┬────────────────────────────────────
|
||||
authors │ [table 1 rows]
|
||||
default-run │ nu
|
||||
description │ A new type of shell
|
||||
documentation │ https://www.nushell.sh/book/
|
||||
edition │ 2018
|
||||
exclude │ [table 1 rows]
|
||||
homepage │ https://www.nushell.sh
|
||||
license │ MIT
|
||||
name │ nu
|
||||
readme │ README.md
|
||||
repository │ https://github.com/nushell/nushell
|
||||
version │ 0.32.0
|
||||
───────────────┴────────────────────────────────────
|
||||
╭───────────────┬────────────────────────────────────╮
|
||||
│ authors │ [list 1 item] │
|
||||
│ default-run │ nu │
|
||||
│ description │ A new type of shell │
|
||||
│ documentation │ https://www.nushell.sh/book/ │
|
||||
│ edition │ 2018 │
|
||||
│ exclude │ [list 1 item] │
|
||||
│ homepage │ https://www.nushell.sh │
|
||||
│ license │ MIT │
|
||||
│ name │ nu │
|
||||
│ readme │ README.md │
|
||||
│ repository │ https://github.com/nushell/nushell │
|
||||
│ rust-version │ 1.60 │
|
||||
│ version │ 0.63.1 │
|
||||
╰───────────────┴────────────────────────────────────╯
|
||||
```
|
||||
|
||||
Finally, we can use commands outside of Nu once we have the data we want:
|
||||
And if needed we can drill down further:
|
||||
|
||||
```shell
|
||||
> open Cargo.toml | get package.version
|
||||
0.32.0
|
||||
0.63.1
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
Nu has early support for configuring the shell. You can refer to the book for a list of [all supported variables](https://www.nushell.sh/book/configuration.html).
|
||||
|
||||
To set one of these variables, you can use `config set`. For example:
|
||||
|
||||
```shell
|
||||
> config set line_editor.edit_mode "vi"
|
||||
> config set path $nu.path
|
||||
```
|
||||
|
||||
### Shells
|
||||
|
||||
Nu will work inside of a single directory and allow you to navigate around your filesystem by default.
|
||||
Nu also offers a way of adding additional working directories that you can jump between, allowing you to work in multiple directories simultaneously.
|
||||
|
||||
To do so, use the `enter` command, which will allow you to create a new "shell" and enter it at the specified path.
|
||||
You can toggle between this new shell and the original shell with the `p` (for previous) and `n` (for next), allowing you to navigate around a ring buffer of shells.
|
||||
Once you're done with a shell, you can `exit` it and remove it from the ring buffer.
|
||||
|
||||
Finally, to get a list of all the current shells, you can use the `shells` command.
|
||||
|
||||
### Plugins
|
||||
|
||||
Nu supports plugins that offer additional functionality to the shell and follow the same structured data model that built-in commands use.
|
||||
This allows you to extend nu for your needs.
|
||||
|
||||
There are a few examples in the `plugins` directory.
|
||||
Nu supports plugins that offer additional functionality to the shell and follow the same structured data model that built-in commands use. There are a few examples in the `crates/nu_plugins_*` directories.
|
||||
|
||||
Plugins are binaries that are available in your path and follow a `nu_plugin_*` naming convention.
|
||||
These binaries interact with nu via a simple JSON-RPC protocol where the command identifies itself and passes along its configuration, making it available for use.
|
||||
@ -231,23 +177,19 @@ If the plugin is a sink, it is given the full vector of final data and is given
|
||||
|
||||
Nu adheres closely to a set of goals that make up its design philosophy. As features are added, they are checked against these goals.
|
||||
|
||||
- First and foremost, Nu is cross-platform. Commands and techniques should carry between platforms and offer consistent first-class support for Windows, macOS, and Linux.
|
||||
- First and foremost, Nu is cross-platform. Commands and techniques should work across platforms and Nu has first-class support for Windows, macOS, and Linux.
|
||||
|
||||
- Nu ensures direct compatibility with existing platform-specific executables that make up people's workflows.
|
||||
- Nu ensures compatibility with existing platform-specific executables.
|
||||
|
||||
- Nu's workflow and tools should have the usability in day-to-day experience of using a shell in 2019 (and beyond).
|
||||
- Nu's workflow and tools should have the usability expected of modern software in 2022 (and beyond).
|
||||
|
||||
- Nu views data as both structured and unstructured. It is a structured shell like PowerShell.
|
||||
- Nu views data as either structured or unstructured. It is a structured shell like PowerShell.
|
||||
|
||||
- Finally, Nu views data functionally. Rather than using mutation, pipelines act as a means to load, change, and save data without mutable state.
|
||||
|
||||
## Commands
|
||||
|
||||
You can find a list of Nu commands, complete with documentation, in [quick command references](https://www.nushell.sh/book/command_reference.html).
|
||||
|
||||
## Progress
|
||||
|
||||
Nu is in heavy development and will naturally change as it matures and people use it. The chart below isn't meant to be exhaustive, but rather helps give an idea for some of the areas of development and their relative completion:
|
||||
Nu is under heavy development and will naturally change as it matures. The chart below isn't meant to be exhaustive, but it helps give an idea for some of the areas of development and their relative maturity:
|
||||
|
||||
| Features | Not started | Prototype | MVP | Preview | Mature | Notes |
|
||||
| ------------- | :---------: | :-------: | :-: | :-----: | :----: | -------------------------------------------------------------------- |
|
||||
@ -270,20 +212,15 @@ Nu is in heavy development and will naturally change as it matures and people us
|
||||
|
||||
Please submit an issue or PR to be added to this list.
|
||||
|
||||
### Integrations
|
||||
- [zoxide](https://github.com/ajeetdsouza/zoxide)
|
||||
- [starship](https://github.com/starship/starship)
|
||||
- [oh-my-posh](https://ohmyposh.dev)
|
||||
- [Couchbase Shell](https://couchbase.sh)
|
||||
- [virtualenv](https://github.com/pypa/virtualenv)
|
||||
### Mentions
|
||||
- [The Python Launcher for Unix](https://github.com/brettcannon/python-launcher#how-do-i-get-a-table-of-python-executables-in-nushell)
|
||||
|
||||
## Contributing
|
||||
|
||||
See [Contributing](CONTRIBUTING.md) for details.
|
||||
|
||||
Thanks to all the people who already contributed!
|
||||
See [Contributing](CONTRIBUTING.md) for details. Thanks to all the people who already contributed!
|
||||
|
||||
<a href="https://github.com/nushell/nushell/graphs/contributors">
|
||||
<img src="https://contributors-img.web.app/image?repo=nushell/nushell&max=500" />
|
||||
|
@ -4,21 +4,21 @@ description = "CLI-related functionality for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-cli"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { path="../nu-test-support", version = "0.63.1" }
|
||||
nu-command = { path = "../nu-command", version = "0.63.1" }
|
||||
nu-test-support = { path="../nu-test-support", version = "0.64.0" }
|
||||
nu-command = { path = "../nu-command", version = "0.64.0" }
|
||||
|
||||
[dependencies]
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.1" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.1" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.1" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.64.0" }
|
||||
nu-path = { path = "../nu-path", version = "0.64.0" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.64.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.64.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.64.0" }
|
||||
nu-ansi-term = "0.46.0"
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.64.0" }
|
||||
reedline = { version = "0.7.0", features = ["bashisms", "sqlite"]}
|
||||
crossterm = "0.23.0"
|
||||
miette = { version = "4.5.0", features = ["fancy"] }
|
||||
thiserror = "1.0.29"
|
||||
@ -26,6 +26,8 @@ fuzzy-matcher = "0.3.7"
|
||||
|
||||
log = "0.4"
|
||||
is_executable = "1.0.1"
|
||||
chrono = "0.4.19"
|
||||
sysinfo = "0.24.1"
|
||||
|
||||
[features]
|
||||
plugin = []
|
||||
|
@ -199,12 +199,19 @@ impl Completer for CommandCompletion {
|
||||
return subcommands;
|
||||
}
|
||||
|
||||
let config = working_set.get_config();
|
||||
let commands = if matches!(self.flat_shape, nu_parser::FlatShape::External)
|
||||
|| matches!(self.flat_shape, nu_parser::FlatShape::InternalCall)
|
||||
|| ((span.end - span.start) == 0)
|
||||
{
|
||||
// we're in a gap or at a command
|
||||
self.complete_commands(working_set, span, offset, true, options.match_algorithm)
|
||||
self.complete_commands(
|
||||
working_set,
|
||||
span,
|
||||
offset,
|
||||
config.enable_external_completion,
|
||||
options.match_algorithm,
|
||||
)
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
@ -59,37 +59,43 @@ impl NuCompleter {
|
||||
fn completion_helper(&mut self, line: &str, pos: usize) -> Vec<Suggestion> {
|
||||
let mut working_set = StateWorkingSet::new(&self.engine_state);
|
||||
let offset = working_set.next_span_start();
|
||||
let (mut new_line, alias_offset) = try_find_alias(line.as_bytes(), &working_set);
|
||||
let initial_line = line.to_string();
|
||||
let mut line = line.to_string();
|
||||
line.insert(pos, 'a');
|
||||
new_line.push(b'a');
|
||||
let pos = offset + pos;
|
||||
let (output, _err) = parse(
|
||||
&mut working_set,
|
||||
Some("completer"),
|
||||
line.as_bytes(),
|
||||
false,
|
||||
&[],
|
||||
);
|
||||
let (output, _err) = parse(&mut working_set, Some("completer"), &new_line, false, &[]);
|
||||
|
||||
for pipeline in output.pipelines.into_iter() {
|
||||
for expr in pipeline.expressions {
|
||||
let flattened: Vec<_> = flatten_expression(&working_set, &expr);
|
||||
|
||||
for (flat_idx, flat) in flattened.iter().enumerate() {
|
||||
if pos >= flat.0.start && pos < flat.0.end {
|
||||
let alias = if alias_offset.is_empty() {
|
||||
0
|
||||
} else {
|
||||
alias_offset[flat_idx]
|
||||
};
|
||||
if pos >= flat.0.start - alias && pos < flat.0.end - alias {
|
||||
// Context variables
|
||||
let most_left_var =
|
||||
most_left_variable(flat_idx, &working_set, flattened.clone());
|
||||
|
||||
// Create a new span
|
||||
let new_span = Span {
|
||||
start: flat.0.start,
|
||||
end: flat.0.end - 1,
|
||||
let new_span = if flat_idx == 0 {
|
||||
Span {
|
||||
start: flat.0.start,
|
||||
end: flat.0.end - 1 - alias,
|
||||
}
|
||||
} else {
|
||||
Span {
|
||||
start: flat.0.start - alias,
|
||||
end: flat.0.end - 1 - alias,
|
||||
}
|
||||
};
|
||||
|
||||
// Parses the prefix
|
||||
let mut prefix = working_set.get_span_contents(flat.0).to_vec();
|
||||
prefix.remove(pos - flat.0.start);
|
||||
prefix.remove(pos - (flat.0.start - alias));
|
||||
|
||||
// Completions that depends on the previous expression (e.g: use, source)
|
||||
if flat_idx > 0 {
|
||||
@ -229,6 +235,74 @@ impl ReedlineCompleter for NuCompleter {
|
||||
}
|
||||
}
|
||||
|
||||
type MatchedAlias<'a> = Vec<(&'a [u8], &'a [u8])>;
|
||||
|
||||
// Handler the completion when giving lines contains at least one alias. (e.g: `g checkout`)
|
||||
// that `g` is an alias of `git`
|
||||
fn try_find_alias(line: &[u8], working_set: &StateWorkingSet) -> (Vec<u8>, Vec<usize>) {
|
||||
// An vector represents the offsets of alias
|
||||
// e.g: the offset is 2 for the alias `g` of `git`
|
||||
let mut alias_offset = vec![];
|
||||
let mut output = vec![];
|
||||
if let Some(matched_alias) = search_alias(line, working_set) {
|
||||
let mut lens = matched_alias.len();
|
||||
for (input_vec, line_vec) in matched_alias {
|
||||
alias_offset.push(line_vec.len() - input_vec.len());
|
||||
output.extend(line_vec);
|
||||
if lens > 1 {
|
||||
output.push(b' ');
|
||||
lens -= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output = line.to_vec();
|
||||
}
|
||||
|
||||
(output, alias_offset)
|
||||
}
|
||||
|
||||
fn search_alias<'a>(input: &'a [u8], working_set: &'a StateWorkingSet) -> Option<MatchedAlias<'a>> {
|
||||
let mut vec_names = vec![];
|
||||
let mut vec_alias = vec![];
|
||||
let mut pos = 0;
|
||||
let mut is_alias = false;
|
||||
for (index, character) in input.iter().enumerate() {
|
||||
if *character == b' ' {
|
||||
let range = &input[pos..index];
|
||||
vec_names.push(range);
|
||||
pos = index + 1;
|
||||
}
|
||||
}
|
||||
// Push the rest to names vector.
|
||||
if pos < input.len() {
|
||||
vec_names.push(&input[pos..]);
|
||||
}
|
||||
|
||||
for name in &vec_names {
|
||||
if let Some(alias_id) = working_set.find_alias(name) {
|
||||
let alias_span = working_set.get_alias(alias_id);
|
||||
is_alias = true;
|
||||
for alias in alias_span {
|
||||
let name = working_set.get_span_contents(*alias);
|
||||
if !name.is_empty() {
|
||||
vec_alias.push(name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vec_alias.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
if is_alias {
|
||||
// Zip names and alias vectors, the original inputs and its aliases mapping.
|
||||
// e.g:(['g'], ['g','i','t'])
|
||||
let output = vec_names.into_iter().zip(vec_alias).collect();
|
||||
Some(output)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// reads the most left variable returning it's name (e.g: $myvar)
|
||||
// and the depth (a.b.c)
|
||||
fn most_left_variable(
|
||||
|
@ -2,12 +2,15 @@ use crate::util::{eval_source, report_error};
|
||||
#[cfg(feature = "plugin")]
|
||||
use log::info;
|
||||
use nu_protocol::engine::{EngineState, Stack, StateDelta, StateWorkingSet};
|
||||
use nu_protocol::{PipelineData, Span};
|
||||
use nu_protocol::{HistoryFileFormat, PipelineData, Span};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
const PLUGIN_FILE: &str = "plugin.nu";
|
||||
|
||||
const HISTORY_FILE_TXT: &str = "history.txt";
|
||||
const HISTORY_FILE_SQLITE: &str = "history.sqlite3";
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
pub fn read_plugin_file(
|
||||
engine_state: &mut EngineState,
|
||||
@ -84,3 +87,14 @@ pub fn eval_config_contents(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_history_path(storage_path: &str, mode: HistoryFileFormat) -> Option<PathBuf> {
|
||||
nu_path::config_dir().map(|mut history_path| {
|
||||
history_path.push(storage_path);
|
||||
history_path.push(match mode {
|
||||
HistoryFileFormat::PlainText => HISTORY_FILE_TXT,
|
||||
HistoryFileFormat::Sqlite => HISTORY_FILE_SQLITE,
|
||||
});
|
||||
history_path
|
||||
})
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use log::trace;
|
||||
use miette::{IntoDiagnostic, Result};
|
||||
use nu_engine::convert_env_values;
|
||||
use nu_parser::parse;
|
||||
use nu_protocol::Type;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
@ -34,7 +35,7 @@ pub fn evaluate_file(
|
||||
|
||||
let _ = parse(&mut working_set, Some(&path), &file, false, &[]);
|
||||
|
||||
if working_set.find_decl(b"main").is_some() {
|
||||
if working_set.find_decl(b"main", &Type::Any).is_some() {
|
||||
let args = format!("main {}", args.join(" "));
|
||||
|
||||
if !eval_source(
|
||||
|
@ -1,6 +1,7 @@
|
||||
use nu_engine::documentation::get_flags_section;
|
||||
use nu_protocol::{engine::EngineState, levenshtein_distance};
|
||||
use reedline::{Completer, Suggestion};
|
||||
use std::fmt::Write;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct NuHelpCompleter(Arc<EngineState>);
|
||||
@ -19,6 +20,10 @@ impl NuHelpCompleter {
|
||||
.filter(|(sig, _, _, _)| {
|
||||
sig.name.to_lowercase().contains(&line.to_lowercase())
|
||||
|| sig.usage.to_lowercase().contains(&line.to_lowercase())
|
||||
|| sig
|
||||
.search_terms
|
||||
.iter()
|
||||
.any(|term| term.to_lowercase().contains(&line.to_lowercase()))
|
||||
|| sig
|
||||
.extra_usage
|
||||
.to_lowercase()
|
||||
@ -49,7 +54,7 @@ impl NuHelpCompleter {
|
||||
long_desc.push_str("\r\n\r\n");
|
||||
}
|
||||
|
||||
long_desc.push_str(&format!("Usage:\r\n > {}\r\n", sig.call_signature()));
|
||||
let _ = write!(long_desc, "Usage:\r\n > {}\r\n", sig.call_signature());
|
||||
|
||||
if !sig.named.is_empty() {
|
||||
long_desc.push_str(&get_flags_section(sig))
|
||||
@ -61,27 +66,28 @@ impl NuHelpCompleter {
|
||||
{
|
||||
long_desc.push_str("\r\nParameters:\r\n");
|
||||
for positional in &sig.required_positional {
|
||||
long_desc
|
||||
.push_str(&format!(" {}: {}\r\n", positional.name, positional.desc));
|
||||
let _ = write!(long_desc, " {}: {}\r\n", positional.name, positional.desc);
|
||||
}
|
||||
for positional in &sig.optional_positional {
|
||||
long_desc.push_str(&format!(
|
||||
let _ = write!(
|
||||
long_desc,
|
||||
" (optional) {}: {}\r\n",
|
||||
positional.name, positional.desc
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(rest_positional) = &sig.rest_positional {
|
||||
long_desc.push_str(&format!(
|
||||
let _ = write!(
|
||||
long_desc,
|
||||
" ...{}: {}\r\n",
|
||||
rest_positional.name, rest_positional.desc
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let extra: Vec<String> = examples
|
||||
.iter()
|
||||
.map(|example| example.example.to_string())
|
||||
.map(|example| example.example.replace('\n', "\r\n"))
|
||||
.collect();
|
||||
|
||||
Suggestion {
|
||||
|
@ -19,6 +19,10 @@ impl Command for NuHighlight {
|
||||
"Syntax highlight the input string."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["syntax", "color", "convert"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -17,7 +17,7 @@ impl Command for Print {
|
||||
Signature::build("print")
|
||||
.rest("rest", SyntaxShape::Any, "the values to print")
|
||||
.switch(
|
||||
"no_newline",
|
||||
"no-newline",
|
||||
"print without inserting a newline for the line ending",
|
||||
Some('n'),
|
||||
)
|
||||
@ -28,6 +28,10 @@ impl Command for Print {
|
||||
"Prints the values given"
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["display"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -36,7 +40,7 @@ impl Command for Print {
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let args: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let no_newline = call.has_flag("no_newline");
|
||||
let no_newline = call.has_flag("no-newline");
|
||||
let head = call.head;
|
||||
|
||||
for arg in args {
|
||||
|
@ -12,21 +12,22 @@ use nu_engine::{convert_env_values, eval_block};
|
||||
use nu_parser::lex;
|
||||
use nu_protocol::{
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
BlockId, PipelineData, PositionalArg, ShellError, Span, Value,
|
||||
BlockId, HistoryFileFormat, PipelineData, PositionalArg, ShellError, Span, Value,
|
||||
};
|
||||
use reedline::{DefaultHinter, Emacs, Vi};
|
||||
use reedline::{DefaultHinter, Emacs, SqliteBackedHistory, Vi};
|
||||
use std::io::{self, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::{sync::atomic::Ordering, time::Instant};
|
||||
use sysinfo::SystemExt;
|
||||
|
||||
const PRE_EXECUTE_MARKER: &str = "\x1b]133;A\x1b\\";
|
||||
const PRE_PROMPT_MARKER: &str = "\x1b]133;C\x1b\\";
|
||||
const PRE_PROMPT_MARKER: &str = "\x1b]133;A\x1b\\";
|
||||
const PRE_EXECUTE_MARKER: &str = "\x1b]133;C\x1b\\";
|
||||
const CMD_FINISHED_MARKER: &str = "\x1b]133;D\x1b\\";
|
||||
const RESET_APPLICATION_MODE: &str = "\x1b[?1l";
|
||||
|
||||
pub fn evaluate_repl(
|
||||
engine_state: &mut EngineState,
|
||||
stack: &mut Stack,
|
||||
history_path: Option<PathBuf>,
|
||||
nushell_path: &str,
|
||||
is_perf_true: bool,
|
||||
) -> Result<()> {
|
||||
use reedline::{FileBackedHistory, Reedline, Signal};
|
||||
@ -84,20 +85,32 @@ pub fn evaluate_repl(
|
||||
info!("setup reedline {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
let mut line_editor = Reedline::create();
|
||||
let history_path = crate::config_files::get_history_path(
|
||||
nushell_path,
|
||||
engine_state.config.history_file_format,
|
||||
);
|
||||
if let Some(history_path) = history_path.as_deref() {
|
||||
if is_perf_true {
|
||||
info!("setup history {}:{}:{}", file!(), line!(), column!());
|
||||
}
|
||||
let history = Box::new(
|
||||
FileBackedHistory::with_file(
|
||||
config.max_history_size as usize,
|
||||
history_path.to_path_buf(),
|
||||
)
|
||||
.into_diagnostic()?,
|
||||
);
|
||||
|
||||
let history: Box<dyn reedline::History> = match engine_state.config.history_file_format {
|
||||
HistoryFileFormat::PlainText => Box::new(
|
||||
FileBackedHistory::with_file(
|
||||
config.max_history_size as usize,
|
||||
history_path.to_path_buf(),
|
||||
)
|
||||
.into_diagnostic()?,
|
||||
),
|
||||
HistoryFileFormat::Sqlite => Box::new(
|
||||
SqliteBackedHistory::with_file(history_path.to_path_buf()).into_diagnostic()?,
|
||||
),
|
||||
};
|
||||
line_editor = line_editor.with_history(history);
|
||||
};
|
||||
|
||||
let sys = sysinfo::System::new();
|
||||
|
||||
loop {
|
||||
if is_perf_true {
|
||||
info!(
|
||||
@ -112,6 +125,10 @@ pub fn evaluate_repl(
|
||||
if let Some(ctrlc) = &mut engine_state.ctrlc {
|
||||
ctrlc.store(false, Ordering::SeqCst);
|
||||
}
|
||||
// Reset the SIGQUIT handler
|
||||
if let Some(sig_quit) = engine_state.get_sig_quit() {
|
||||
sig_quit.store(false, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
config = engine_state.get_config();
|
||||
|
||||
@ -272,8 +289,9 @@ pub fn evaluate_repl(
|
||||
|
||||
config = engine_state.get_config();
|
||||
|
||||
if config.shell_integration {
|
||||
run_ansi_sequence(PRE_EXECUTE_MARKER)?;
|
||||
let shell_integration = config.shell_integration;
|
||||
if shell_integration {
|
||||
run_ansi_sequence(PRE_PROMPT_MARKER)?;
|
||||
}
|
||||
|
||||
let prompt =
|
||||
@ -294,6 +312,20 @@ pub fn evaluate_repl(
|
||||
|
||||
match input {
|
||||
Ok(Signal::Success(s)) => {
|
||||
let history_supports_meta =
|
||||
matches!(config.history_file_format, HistoryFileFormat::Sqlite);
|
||||
if history_supports_meta && !s.is_empty() {
|
||||
line_editor
|
||||
.update_last_command_context(&|mut c| {
|
||||
c.start_timestamp = Some(chrono::Utc::now());
|
||||
c.hostname = sys.host_name();
|
||||
|
||||
c.cwd = Some(StateWorkingSet::new(engine_state).get_cwd());
|
||||
c
|
||||
})
|
||||
.into_diagnostic()?; // todo: don't stop repl if error here?
|
||||
}
|
||||
|
||||
// Right before we start running the code the user gave us,
|
||||
// fire the "pre_execution" hook
|
||||
if let Some(hook) = &config.hooks.pre_execution {
|
||||
@ -303,9 +335,9 @@ pub fn evaluate_repl(
|
||||
}
|
||||
}
|
||||
|
||||
if config.shell_integration {
|
||||
if shell_integration {
|
||||
run_ansi_sequence(RESET_APPLICATION_MODE)?;
|
||||
run_ansi_sequence(PRE_PROMPT_MARKER)?;
|
||||
run_ansi_sequence(PRE_EXECUTE_MARKER)?;
|
||||
if let Some(cwd) = stack.get_env_var(engine_state, "PWD") {
|
||||
let path = cwd.as_string()?;
|
||||
// Try to abbreviate string for windows title
|
||||
@ -395,11 +427,12 @@ pub fn evaluate_repl(
|
||||
PipelineData::new(Span::new(0, 0)),
|
||||
);
|
||||
}
|
||||
let cmd_duration = start_time.elapsed();
|
||||
|
||||
stack.add_env_var(
|
||||
"CMD_DURATION_MS".into(),
|
||||
Value::String {
|
||||
val: format!("{}", start_time.elapsed().as_millis()),
|
||||
val: format!("{}", cmd_duration.as_millis()),
|
||||
span: Span { start: 0, end: 0 },
|
||||
},
|
||||
);
|
||||
@ -411,12 +444,35 @@ pub fn evaluate_repl(
|
||||
let _ = std::env::set_current_dir(path);
|
||||
engine_state.add_env_var("PWD".into(), cwd);
|
||||
}
|
||||
|
||||
if history_supports_meta && !s.is_empty() {
|
||||
line_editor
|
||||
.update_last_command_context(&|mut c| {
|
||||
c.duration = Some(cmd_duration);
|
||||
c.exit_status = stack
|
||||
.get_env_var(engine_state, "LAST_EXIT_CODE")
|
||||
.and_then(|e| e.as_i64().ok());
|
||||
c
|
||||
})
|
||||
.into_diagnostic()?; // todo: don't stop repl if error here?
|
||||
}
|
||||
|
||||
if shell_integration {
|
||||
// FIXME: use variant with exit code, if apropriate
|
||||
run_ansi_sequence(CMD_FINISHED_MARKER)?;
|
||||
}
|
||||
}
|
||||
Ok(Signal::CtrlC) => {
|
||||
// `Reedline` clears the line content. New prompt is shown
|
||||
if shell_integration {
|
||||
run_ansi_sequence(CMD_FINISHED_MARKER)?;
|
||||
}
|
||||
}
|
||||
Ok(Signal::CtrlD) => {
|
||||
// When exiting clear to a new line
|
||||
if shell_integration {
|
||||
run_ansi_sequence(CMD_FINISHED_MARKER)?;
|
||||
}
|
||||
println!();
|
||||
break;
|
||||
}
|
||||
@ -425,6 +481,9 @@ pub fn evaluate_repl(
|
||||
if !message.contains("duration") {
|
||||
println!("Error: {:?}", err);
|
||||
}
|
||||
if shell_integration {
|
||||
run_ansi_sequence(CMD_FINISHED_MARKER)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,35 @@ use nu_protocol::{
|
||||
};
|
||||
#[cfg(windows)]
|
||||
use nu_utils::enable_vt_processing;
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// This will collect environment variables from std::env and adds them to a stack.
|
||||
//
|
||||
// In order to ensure the values have spans, it first creates a dummy file, writes the collected
|
||||
// env vars into it (in a "NAME"="value" format, quite similar to the output of the Unix 'env'
|
||||
// tool), then uses the file to get the spans. The file stays in memory, no filesystem IO is done.
|
||||
pub fn gather_parent_env_vars(engine_state: &mut EngineState) {
|
||||
gather_env_vars(std::env::vars(), engine_state);
|
||||
//
|
||||
// The "PWD" env value will be forced to `init_cwd`.
|
||||
// The reason to use `init_cwd`:
|
||||
//
|
||||
// While gathering parent env vars, the parent `PWD` may not be the same as `current working directory`.
|
||||
// Consider to the following command as the case (assume we execute command inside `/tmp`):
|
||||
//
|
||||
// tmux split-window -v -c "#{pane_current_path}"
|
||||
//
|
||||
// Here nu execute external command `tmux`, and tmux starts a new `nushell`, with `init_cwd` value "#{pane_current_path}".
|
||||
// But at the same time `PWD` still remains to be `/tmp`.
|
||||
//
|
||||
// In this scenario, the new `nushell`'s PWD should be "#{pane_current_path}" rather init_cwd.
|
||||
pub fn gather_parent_env_vars(engine_state: &mut EngineState, init_cwd: &Path) {
|
||||
gather_env_vars(std::env::vars(), engine_state, init_cwd);
|
||||
}
|
||||
|
||||
fn gather_env_vars(vars: impl Iterator<Item = (String, String)>, engine_state: &mut EngineState) {
|
||||
fn gather_env_vars(
|
||||
vars: impl Iterator<Item = (String, String)>,
|
||||
engine_state: &mut EngineState,
|
||||
init_cwd: &Path,
|
||||
) {
|
||||
fn report_capture_error(engine_state: &EngineState, env_str: &str, msg: &str) {
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
report_error(
|
||||
@ -43,35 +60,31 @@ fn gather_env_vars(vars: impl Iterator<Item = (String, String)>, engine_state: &
|
||||
}
|
||||
|
||||
let mut fake_env_file = String::new();
|
||||
let mut has_pwd = false;
|
||||
|
||||
// Write all the env vars into a fake file
|
||||
for (name, val) in vars {
|
||||
if name == "PWD" {
|
||||
has_pwd = true;
|
||||
}
|
||||
put_env_to_fake_file(&name, &val, &mut fake_env_file);
|
||||
}
|
||||
|
||||
if !has_pwd {
|
||||
match std::env::current_dir() {
|
||||
Ok(cwd) => {
|
||||
put_env_to_fake_file("PWD", &cwd.to_string_lossy(), &mut fake_env_file);
|
||||
}
|
||||
Err(e) => {
|
||||
// Could not capture current working directory
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
report_error(
|
||||
&working_set,
|
||||
&ShellError::GenericError(
|
||||
"Current directory not found".to_string(),
|
||||
"".to_string(),
|
||||
None,
|
||||
Some(format!("Retrieving current directory failed: {:?}", e)),
|
||||
Vec::new(),
|
||||
),
|
||||
);
|
||||
}
|
||||
match init_cwd.to_str() {
|
||||
Some(cwd) => {
|
||||
put_env_to_fake_file("PWD", cwd, &mut fake_env_file);
|
||||
}
|
||||
None => {
|
||||
// Could not capture current working directory
|
||||
let working_set = StateWorkingSet::new(engine_state);
|
||||
report_error(
|
||||
&working_set,
|
||||
&ShellError::GenericError(
|
||||
"Current directory is not a valid utf-8 path".to_string(),
|
||||
"".to_string(),
|
||||
None,
|
||||
Some(format!(
|
||||
"Retrieving current directory failed: {:?} not a valid utf-8 path",
|
||||
init_cwd
|
||||
)),
|
||||
Vec::new(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,6 +327,7 @@ mod test {
|
||||
]
|
||||
.into_iter(),
|
||||
&mut engine_state,
|
||||
Path::new("t"),
|
||||
);
|
||||
|
||||
let env = engine_state.render_env_vars();
|
||||
|
@ -18,7 +18,7 @@ fn variables_completions() {
|
||||
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);
|
||||
|
||||
// Test completions for $nu
|
||||
let suggestions = completer.complete("my-command ".into(), 11);
|
||||
let suggestions = completer.complete("my-command ", 11);
|
||||
|
||||
assert_eq!(3, suggestions.len());
|
||||
|
||||
|
@ -12,7 +12,7 @@ fn flag_completions() {
|
||||
// Instatiate a new completer
|
||||
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);
|
||||
// Test completions for the 'ls' flags
|
||||
let suggestions = completer.complete("ls -".into(), 4);
|
||||
let suggestions = completer.complete("ls -", 4);
|
||||
|
||||
assert_eq!(12, suggestions.len());
|
||||
|
||||
|
@ -89,7 +89,7 @@ pub fn merge_input(
|
||||
dir: PathBuf,
|
||||
) -> Result<(), ShellError> {
|
||||
let (block, delta) = {
|
||||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
|
||||
let (block, err) = parse(&mut working_set, None, input, false, &[]);
|
||||
|
||||
@ -98,7 +98,7 @@ pub fn merge_input(
|
||||
(block, working_set.render())
|
||||
};
|
||||
assert!(eval_block(
|
||||
&engine_state,
|
||||
engine_state,
|
||||
stack,
|
||||
&block,
|
||||
PipelineData::Value(
|
||||
|
@ -17,15 +17,16 @@ fn variables_completions() {
|
||||
let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack);
|
||||
|
||||
// Test completions for $nu
|
||||
let suggestions = completer.complete("$nu.".into(), 4);
|
||||
let suggestions = completer.complete("$nu.", 4);
|
||||
|
||||
assert_eq!(8, suggestions.len());
|
||||
assert_eq!(9, suggestions.len());
|
||||
|
||||
let expected: Vec<String> = vec![
|
||||
"config-path".into(),
|
||||
"env-path".into(),
|
||||
"history-path".into(),
|
||||
"home-path".into(),
|
||||
"loginshell-path".into(),
|
||||
"os-info".into(),
|
||||
"pid".into(),
|
||||
"scope".into(),
|
||||
@ -36,7 +37,7 @@ fn variables_completions() {
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $nu.h (filter)
|
||||
let suggestions = completer.complete("$nu.h".into(), 5);
|
||||
let suggestions = completer.complete("$nu.h", 5);
|
||||
|
||||
assert_eq!(2, suggestions.len());
|
||||
|
||||
@ -46,7 +47,7 @@ fn variables_completions() {
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for custom var
|
||||
let suggestions = completer.complete("$actor.".into(), 7);
|
||||
let suggestions = completer.complete("$actor.", 7);
|
||||
|
||||
assert_eq!(2, suggestions.len());
|
||||
|
||||
@ -56,7 +57,7 @@ fn variables_completions() {
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for custom var (filtering)
|
||||
let suggestions = completer.complete("$actor.n".into(), 7);
|
||||
let suggestions = completer.complete("$actor.n", 8);
|
||||
|
||||
assert_eq!(1, suggestions.len());
|
||||
|
||||
@ -66,7 +67,7 @@ fn variables_completions() {
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $env
|
||||
let suggestions = completer.complete("$env.".into(), 5);
|
||||
let suggestions = completer.complete("$env.", 5);
|
||||
|
||||
assert_eq!(2, suggestions.len());
|
||||
|
||||
@ -76,7 +77,7 @@ fn variables_completions() {
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $env
|
||||
let suggestions = completer.complete("$env.T".into(), 5);
|
||||
let suggestions = completer.complete("$env.T", 6);
|
||||
|
||||
assert_eq!(1, suggestions.len());
|
||||
|
||||
|
@ -4,11 +4,11 @@ description = "Color configuration code used by Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-color-config"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
|
||||
[dependencies]
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-json = { path = "../nu-json", version = "0.63.1" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.64.0" }
|
||||
nu-ansi-term = "0.46.0"
|
||||
nu-json = { path = "../nu-json", version = "0.64.0" }
|
||||
nu-table = { path = "../nu-table", version = "0.64.0" }
|
||||
serde = { version="1.0.123", features=["derive"] }
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_ansi_term::{Color, Style};
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Deserialize, PartialEq, Debug)]
|
||||
#[derive(Deserialize, PartialEq, Eq, Debug)]
|
||||
pub struct NuStyle {
|
||||
pub fg: Option<String>,
|
||||
pub bg: Option<String>,
|
||||
|
@ -4,26 +4,26 @@ description = "Nushell's built-in commands"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-command"
|
||||
version = "0.63.1"
|
||||
version = "0.64.0"
|
||||
build = "build.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.1" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.1" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.1" }
|
||||
nu-json = { path = "../nu-json", version = "0.63.1" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.1" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.1" }
|
||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-system = { path = "../nu-system", version = "0.63.1" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.1" }
|
||||
nu-term-grid = { path = "../nu-term-grid", version = "0.63.1" }
|
||||
nu-test-support = { path = "../nu-test-support", version = "0.63.1" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.64.0" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.64.0" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.64.0" }
|
||||
nu-json = { path = "../nu-json", version = "0.64.0" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.64.0" }
|
||||
nu-path = { path = "../nu-path", version = "0.64.0" }
|
||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.64.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.64.0" }
|
||||
nu-system = { path = "../nu-system", version = "0.64.0" }
|
||||
nu-table = { path = "../nu-table", version = "0.64.0" }
|
||||
nu-term-grid = { path = "../nu-term-grid", version = "0.64.0" }
|
||||
nu-test-support = { path = "../nu-test-support", version = "0.64.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.64.0" }
|
||||
nu-ansi-term = "0.46.0"
|
||||
|
||||
# Potential dependencies for extras
|
||||
alphanumeric-sort = "1.4.4"
|
||||
@ -47,6 +47,7 @@ htmlescape = "0.3.1"
|
||||
ical = "0.7.0"
|
||||
indexmap = { version="1.7", features=["serde-1"] }
|
||||
Inflector = "0.11"
|
||||
is-root = "0.1.2"
|
||||
itertools = "0.10.0"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.14"
|
||||
@ -82,7 +83,7 @@ unicode-segmentation = "1.8.0"
|
||||
url = "2.2.1"
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
||||
which = { version = "4.2.2", optional = true }
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
reedline = { version = "0.7.0", features = ["bashisms", "sqlite"]}
|
||||
wax = { version = "0.4.0", features = ["diagnostics"] }
|
||||
rusqlite = { version = "0.27.0", features = ["bundled"], optional = true }
|
||||
sqlparser = { version = "0.16.0", features = ["serde"], optional = true }
|
||||
@ -107,6 +108,15 @@ features = [
|
||||
"dynamic_groupby"
|
||||
]
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows]
|
||||
version = "0.37.0"
|
||||
features = [
|
||||
"alloc",
|
||||
"Win32_Foundation",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_SystemServices",
|
||||
]
|
||||
|
||||
[features]
|
||||
trash-support = ["trash"]
|
||||
which-support = ["which"]
|
||||
|
@ -191,7 +191,10 @@ pub fn action(input: &Value, span: Span, radix: u32) -> Value {
|
||||
span,
|
||||
},
|
||||
_ => Value::Error {
|
||||
error: ShellError::UnsupportedInput("'into int' for unsupported type".into(), span),
|
||||
error: ShellError::UnsupportedInput(
|
||||
format!("'into int' for unsupported type '{}'", input.get_type()),
|
||||
span,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,10 @@ impl Command for Alias {
|
||||
true
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["abbr", "aka", "fn", "func", "function"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
|
@ -1,14 +1,13 @@
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Value,
|
||||
Category, Example, HistoryFileFormat, IntoInterruptiblePipelineData, PipelineData, ShellError,
|
||||
Signature, Value,
|
||||
};
|
||||
use reedline::{
|
||||
FileBackedHistory, History as ReedlineHistory, SearchDirection, SearchQuery,
|
||||
SqliteBackedHistory,
|
||||
};
|
||||
|
||||
const NEWLINE_ESCAPE_CODE: &str = "<\\n>";
|
||||
|
||||
fn decode_newlines(escaped: &str) -> String {
|
||||
escaped.replace(NEWLINE_ESCAPE_CODE, "\n")
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct History;
|
||||
@ -36,44 +35,74 @@ impl Command for History {
|
||||
_input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let head = call.head;
|
||||
// todo for sqlite history this command should be an alias to `open ~/.config/nushell/history.sqlite3 | get history`
|
||||
if let Some(config_path) = nu_path::config_dir() {
|
||||
let clear = call.has_flag("clear");
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let mut history_path = config_path;
|
||||
history_path.push("nushell");
|
||||
history_path.push("history.txt");
|
||||
match engine_state.config.history_file_format {
|
||||
HistoryFileFormat::Sqlite => {
|
||||
history_path.push("history.sqlite3");
|
||||
}
|
||||
HistoryFileFormat::PlainText => {
|
||||
history_path.push("history.txt");
|
||||
}
|
||||
}
|
||||
|
||||
if clear {
|
||||
let _ = std::fs::remove_file(history_path);
|
||||
// TODO: FIXME also clear the auxiliary files when using sqlite
|
||||
Ok(PipelineData::new(head))
|
||||
} else {
|
||||
let contents = std::fs::read_to_string(history_path);
|
||||
let history_reader: Option<Box<dyn ReedlineHistory>> =
|
||||
match engine_state.config.history_file_format {
|
||||
HistoryFileFormat::Sqlite => SqliteBackedHistory::with_file(history_path)
|
||||
.map(|inner| {
|
||||
let boxed: Box<dyn ReedlineHistory> = Box::new(inner);
|
||||
boxed
|
||||
})
|
||||
.ok(),
|
||||
|
||||
if let Ok(contents) = contents {
|
||||
Ok(contents
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(move |(index, command)| Value::Record {
|
||||
cols: vec!["command".to_string(), "index".to_string()],
|
||||
vals: vec![
|
||||
Value::String {
|
||||
val: decode_newlines(command),
|
||||
span: head,
|
||||
},
|
||||
Value::Int {
|
||||
val: index as i64,
|
||||
span: head,
|
||||
},
|
||||
],
|
||||
span: head,
|
||||
HistoryFileFormat::PlainText => FileBackedHistory::with_file(
|
||||
engine_state.config.max_history_size as usize,
|
||||
history_path,
|
||||
)
|
||||
.map(|inner| {
|
||||
let boxed: Box<dyn ReedlineHistory> = Box::new(inner);
|
||||
boxed
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.into_iter()
|
||||
.into_pipeline_data(ctrlc))
|
||||
} else {
|
||||
Err(ShellError::FileNotFound(head))
|
||||
}
|
||||
.ok(),
|
||||
};
|
||||
|
||||
let data = history_reader
|
||||
.and_then(|h| {
|
||||
h.search(SearchQuery::everything(SearchDirection::Forward))
|
||||
.ok()
|
||||
})
|
||||
.map(move |entries| {
|
||||
entries
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(move |(idx, entry)| Value::Record {
|
||||
cols: vec!["command".to_string(), "index".to_string()],
|
||||
vals: vec![
|
||||
Value::String {
|
||||
val: entry.command_line,
|
||||
span: head,
|
||||
},
|
||||
Value::Int {
|
||||
val: idx as i64,
|
||||
span: head,
|
||||
},
|
||||
],
|
||||
span: head,
|
||||
})
|
||||
})
|
||||
.ok_or(ShellError::FileNotFound(head))?
|
||||
.into_pipeline_data(ctrlc);
|
||||
Ok(data)
|
||||
}
|
||||
} else {
|
||||
Err(ShellError::FileNotFound(head))
|
||||
|
@ -24,7 +24,7 @@ impl Command for OrderByDb {
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.switch("ascending", "Order by ascending values", Some('a'))
|
||||
.switch("nulls_first", "Show nulls first in order", Some('n'))
|
||||
.switch("nulls-first", "Show nulls first in order", Some('n'))
|
||||
.rest(
|
||||
"select",
|
||||
SyntaxShape::Any,
|
||||
@ -40,10 +40,10 @@ impl Command for OrderByDb {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "orders query by a column",
|
||||
example: r#"db open db.mysql
|
||||
| db from table_a
|
||||
| db select a
|
||||
| db order-by a
|
||||
example: r#"db open db.mysql
|
||||
| db from table_a
|
||||
| db select a
|
||||
| db order-by a
|
||||
| db describe"#,
|
||||
result: None,
|
||||
}]
|
||||
@ -57,7 +57,7 @@ impl Command for OrderByDb {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let asc = call.has_flag("ascending");
|
||||
let nulls_first = call.has_flag("nulls_first");
|
||||
let nulls_first = call.has_flag("nulls-first");
|
||||
let expressions: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let expressions = Value::List {
|
||||
vals: expressions,
|
||||
|
@ -52,7 +52,7 @@ impl CustomValue for ExprDb {
|
||||
fn follow_path_int(&self, count: usize, span: Span) -> Result<Value, ShellError> {
|
||||
let path = PathMember::Int { val: count, span };
|
||||
|
||||
ExprDb::expr_to_value(self.as_ref(), span).follow_cell_path(&[path])
|
||||
ExprDb::expr_to_value(self.as_ref(), span).follow_cell_path(&[path], false)
|
||||
}
|
||||
|
||||
fn follow_path_string(&self, column_name: String, span: Span) -> Result<Value, ShellError> {
|
||||
@ -61,7 +61,7 @@ impl CustomValue for ExprDb {
|
||||
span,
|
||||
};
|
||||
|
||||
ExprDb::expr_to_value(self.as_ref(), span).follow_cell_path(&[path])
|
||||
ExprDb::expr_to_value(self.as_ref(), span).follow_cell_path(&[path], false)
|
||||
}
|
||||
|
||||
fn typetag_name(&self) -> &'static str {
|
||||
@ -91,7 +91,7 @@ impl CustomValue for ExprDb {
|
||||
Value::Bool { val, .. } => Ok(Expr::Value(sqlparser::ast::Value::Boolean(*val))),
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: Type::Custom,
|
||||
lhs_ty: Type::Custom(self.typetag_name().into()),
|
||||
lhs_span,
|
||||
rhs_ty: right.get_type(),
|
||||
rhs_span: right.span()?,
|
||||
@ -112,6 +112,7 @@ impl CustomValue for ExprDb {
|
||||
Operator::Multiply => Ok(BinaryOperator::Multiply),
|
||||
Operator::Divide => Ok(BinaryOperator::Divide),
|
||||
Operator::Modulo => Ok(BinaryOperator::Modulo),
|
||||
Operator::FloorDivision => Ok(BinaryOperator::Divide),
|
||||
Operator::And => Ok(BinaryOperator::And),
|
||||
Operator::Or => Ok(BinaryOperator::Or),
|
||||
Operator::In
|
||||
|
@ -56,7 +56,7 @@ impl CustomValue for SelectDb {
|
||||
fn follow_path_int(&self, count: usize, span: Span) -> Result<Value, ShellError> {
|
||||
let path = PathMember::Int { val: count, span };
|
||||
|
||||
SelectDb::select_to_value(self.as_ref(), span).follow_cell_path(&[path])
|
||||
SelectDb::select_to_value(self.as_ref(), span).follow_cell_path(&[path], false)
|
||||
}
|
||||
|
||||
fn follow_path_string(&self, column_name: String, span: Span) -> Result<Value, ShellError> {
|
||||
@ -64,7 +64,7 @@ impl CustomValue for SelectDb {
|
||||
val: column_name,
|
||||
span,
|
||||
};
|
||||
SelectDb::select_to_value(self.as_ref(), span).follow_cell_path(&[path])
|
||||
SelectDb::select_to_value(self.as_ref(), span).follow_cell_path(&[path], false)
|
||||
}
|
||||
|
||||
fn typetag_name(&self) -> &'static str {
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use super::super::values::{Axis, Column, NuDataFrame};
|
||||
@ -12,7 +12,7 @@ pub struct AppendDF;
|
||||
|
||||
impl Command for AppendDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr append"
|
||||
"append"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -30,8 +30,8 @@ impl Command for AppendDF {
|
||||
vec![
|
||||
Example {
|
||||
description: "Appends a dataframe as new columns",
|
||||
example: r#"let a = ([[a b]; [1 2] [3 4]] | dfr to-df);
|
||||
$a | dfr append $a"#,
|
||||
example: r#"let a = ([[a b]; [1 2] [3 4]] | to-df);
|
||||
$a | append $a"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -57,8 +57,8 @@ impl Command for AppendDF {
|
||||
},
|
||||
Example {
|
||||
description: "Appends a dataframe merging at the end of columns",
|
||||
example: r#"let a = ([[a b]; [1 2] [3 4]] | dfr to-df);
|
||||
$a | dfr append $a --col"#,
|
||||
example: r#"let a = ([[a b]; [1 2] [3 4]] | to-df);
|
||||
$a | append $a --col"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -87,6 +87,14 @@ impl Command for AppendDF {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -1,87 +0,0 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
use super::super::values::{Column, NuDataFrame};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ColumnDF;
|
||||
|
||||
impl Command for ColumnDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr column"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Returns the selected column"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required("column", SyntaxShape::String, "column name")
|
||||
.category(Category::Custom("dataframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Returns the selected column as series",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr column a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
)])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
command(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn command(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let column: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let df = NuDataFrame::try_from_pipeline(input, call.head)?;
|
||||
|
||||
let res = df.as_ref().column(&column.item).map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error selecting column".into(),
|
||||
e.to_string(),
|
||||
Some(column.span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
})?;
|
||||
|
||||
NuDataFrame::try_from_series(vec![res.clone()], call.head)
|
||||
.map(|df| PipelineData::Value(NuDataFrame::into_value(df, call.head), None))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(ColumnDF {})])
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
use nu_engine::get_full_help;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, IntoPipelineData, PipelineData, ShellError, Signature, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Dataframe;
|
||||
|
||||
impl Command for Dataframe {
|
||||
fn name(&self) -> &str {
|
||||
"dfr"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Dataframe commands"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).category(Category::Custom("dataframe".into()))
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(
|
||||
&Dataframe.signature(),
|
||||
&Dataframe.examples(),
|
||||
engine_state,
|
||||
stack,
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::{
|
||||
chunked_array::ChunkedArray,
|
||||
@ -19,7 +19,7 @@ pub struct DescribeDF;
|
||||
|
||||
impl Command for DescribeDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr describe"
|
||||
"describe"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -40,7 +40,7 @@ impl Command for DescribeDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "dataframe description",
|
||||
example: "[[a b]; [1 1] [1 1]] | dfr to-df | dfr describe",
|
||||
example: "[[a b]; [1 1] [1 1]] | to-df | describe",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -95,6 +95,14 @@ impl Command for DescribeDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use super::super::values::utils::convert_columns;
|
||||
@ -13,7 +13,7 @@ pub struct DropDF;
|
||||
|
||||
impl Command for DropDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr drop"
|
||||
"drop"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -29,7 +29,7 @@ impl Command for DropDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "drop column a",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr drop a",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | drop a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"b".to_string(),
|
||||
@ -41,6 +41,14 @@ impl Command for DropDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::UniqueKeepStrategy;
|
||||
|
||||
@ -14,7 +14,7 @@ pub struct DropDuplicates;
|
||||
|
||||
impl Command for DropDuplicates {
|
||||
fn name(&self) -> &str {
|
||||
"dfr drop-duplicates"
|
||||
"drop-duplicates"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -40,7 +40,7 @@ impl Command for DropDuplicates {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "drop duplicates",
|
||||
example: "[[a b]; [1 2] [3 4] [1 2]] | dfr to-df | dfr drop-duplicates",
|
||||
example: "[[a b]; [1 2] [3 4] [1 2]] | to-df | drop-duplicates",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -58,6 +58,14 @@ impl Command for DropDuplicates {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use super::super::values::utils::convert_columns_string;
|
||||
@ -13,7 +13,7 @@ pub struct DropNulls;
|
||||
|
||||
impl Command for DropNulls {
|
||||
fn name(&self) -> &str {
|
||||
"dfr drop-nulls"
|
||||
"drop-nulls"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -34,10 +34,10 @@ impl Command for DropNulls {
|
||||
vec![
|
||||
Example {
|
||||
description: "drop null values in dataframe",
|
||||
example: r#"let df = ([[a b]; [1 2] [3 0] [1 2]] | dfr to-df);
|
||||
example: r#"let df = ([[a b]; [1 2] [3 0] [1 2]] | to-df);
|
||||
let res = ($df.b / $df.b);
|
||||
let a = ($df | dfr with-column $res --name res);
|
||||
$a | dfr drop-nulls"#,
|
||||
let a = ($df | with-column $res --name res);
|
||||
$a | drop-nulls"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -59,8 +59,8 @@ impl Command for DropNulls {
|
||||
},
|
||||
Example {
|
||||
description: "drop null values in dataframe",
|
||||
example: r#"let s = ([1 2 0 0 3 4] | dfr to-df);
|
||||
($s / $s) | dfr drop-nulls"#,
|
||||
example: r#"let s = ([1 2 0 0 3 4] | to-df);
|
||||
($s / $s) | drop-nulls"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"div_0_0".to_string(),
|
||||
@ -78,6 +78,14 @@ impl Command for DropNulls {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -10,7 +10,7 @@ pub struct DataTypes;
|
||||
|
||||
impl Command for DataTypes {
|
||||
fn name(&self) -> &str {
|
||||
"dfr dtypes"
|
||||
"dtypes"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -24,7 +24,7 @@ impl Command for DataTypes {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Dataframe dtypes",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr dtypes",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | dtypes",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -42,6 +42,14 @@ impl Command for DataTypes {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::DataFrameOps;
|
||||
|
||||
@ -11,7 +11,7 @@ pub struct Dummies;
|
||||
|
||||
impl Command for Dummies {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-dummies"
|
||||
"to-dummies"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for Dummies {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create new dataframe with dummy variables from a dataframe",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-dummies",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | to-dummies",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -52,7 +52,7 @@ impl Command for Dummies {
|
||||
},
|
||||
Example {
|
||||
description: "Create new dataframe with dummy variables from a series",
|
||||
example: "[1 2 2 3 3] | dfr to-df | dfr to-dummies",
|
||||
example: "[1 2 2 3 3] | to-df | to-dummies",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -93,6 +93,14 @@ impl Command for Dummies {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::LazyFrame;
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct FilterWith;
|
||||
|
||||
impl Command for FilterWith {
|
||||
fn name(&self) -> &str {
|
||||
"dfr filter-with"
|
||||
"filter-with"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -29,23 +29,45 @@ impl Command for FilterWith {
|
||||
SyntaxShape::Any,
|
||||
"boolean mask used to filter data",
|
||||
)
|
||||
.category(Category::Custom("dataframe".into()))
|
||||
.category(Category::Custom("dataframe or lazyframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Filter dataframe using a bool mask",
|
||||
example: r#"let mask = ([true false] | dfr to-df);
|
||||
[[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(2)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
vec![
|
||||
Example {
|
||||
description: "Filter dataframe using a bool mask",
|
||||
example: r#"let mask = ([true false] | to-df);
|
||||
[[a b]; [1 2] [3 4]] | to-df | filter-with $mask"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(2)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Filter dataframe using an expression",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | filter-with ((col a) > 1)",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(3)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(4)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -60,16 +82,9 @@ impl Command for FilterWith {
|
||||
if NuLazyFrame::can_downcast(&value) {
|
||||
let df = NuLazyFrame::try_from_value(value)?;
|
||||
command_lazy(engine_state, stack, call, df)
|
||||
} else if NuDataFrame::can_downcast(&value) {
|
||||
} else {
|
||||
let df = NuDataFrame::try_from_value(value)?;
|
||||
command_eager(engine_state, stack, call, df)
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or query".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,31 +96,42 @@ fn command_eager(
|
||||
df: NuDataFrame,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mask_value: Value = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let mask_span = mask_value.span()?;
|
||||
let mask = NuDataFrame::try_from_value(mask_value)?.as_series(mask_span)?;
|
||||
let mask = mask.bool().map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error casting to bool".into(),
|
||||
e.to_string(),
|
||||
Some(mask_span),
|
||||
Some("Perhaps you want to use a series with booleans as mask".into()),
|
||||
Vec::new(),
|
||||
)
|
||||
})?;
|
||||
|
||||
df.as_ref()
|
||||
.filter(mask)
|
||||
.map_err(|e| {
|
||||
if NuExpression::can_downcast(&mask_value) {
|
||||
let expression = NuExpression::try_from_value(mask_value)?;
|
||||
let lazy = NuLazyFrame::new(true, df.lazy());
|
||||
let lazy = lazy.apply_with_expr(expression, LazyFrame::filter);
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuLazyFrame::into_value(lazy, call.head)?,
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
let mask = NuDataFrame::try_from_value(mask_value)?.as_series(mask_span)?;
|
||||
let mask = mask.bool().map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error calculating dummies".into(),
|
||||
"Error casting to bool".into(),
|
||||
e.to_string(),
|
||||
Some(call.head),
|
||||
Some("The only allowed column types for dummies are String or Int".into()),
|
||||
Some(mask_span),
|
||||
Some("Perhaps you want to use a series with booleans as mask".into()),
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| PipelineData::Value(NuDataFrame::dataframe_into_value(df, call.head), None))
|
||||
})?;
|
||||
|
||||
df.as_ref()
|
||||
.filter(mask)
|
||||
.map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error filtering dataframe".into(),
|
||||
e.to_string(),
|
||||
Some(call.head),
|
||||
Some("The only allowed column types for dummies are String or Int".into()),
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| PipelineData::Value(NuDataFrame::dataframe_into_value(df, call.head), None))
|
||||
}
|
||||
}
|
||||
|
||||
fn command_lazy(
|
||||
@ -120,7 +146,7 @@ fn command_lazy(
|
||||
let lazy = lazy.apply_with_expr(expr, LazyFrame::filter);
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuLazyFrame::into_value(lazy, call.head),
|
||||
NuLazyFrame::into_value(lazy, call.head)?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
@ -129,9 +155,10 @@ fn command_lazy(
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::ExprCol;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(FilterWith {})])
|
||||
test_dataframe(vec![Box::new(FilterWith {}), Box::new(ExprCol {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
use super::super::values::{utils::DEFAULT_ROWS, Column, NuDataFrame};
|
||||
use crate::dataframe::values::NuExpression;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,11 +11,11 @@ pub struct FirstDF;
|
||||
|
||||
impl Command for FirstDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr first"
|
||||
"first"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Creates new dataframe with first rows or creates a first expression"
|
||||
"Creates new dataframe with first rows"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
@ -26,25 +25,26 @@ impl Command for FirstDF {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create new dataframe with head rows",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr first 1",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(2)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Creates a first expression from a column",
|
||||
example: "dfr col a | dfr first",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
vec![Example {
|
||||
description: "Create new dataframe with head rows",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | first 1",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(2)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -54,27 +54,8 @@ impl Command for FirstDF {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value = input.into_value(call.head);
|
||||
|
||||
if NuExpression::can_downcast(&value) {
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let expr: NuExpression = expr.into_polars().is_null().into();
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
} else if NuDataFrame::can_downcast(&value) {
|
||||
let df = NuDataFrame::try_from_value(value)?;
|
||||
command(engine_state, stack, call, df)
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or query".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
let df = NuDataFrame::try_from_pipeline(input, call.head)?;
|
||||
command(engine_state, stack, call, df)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::values::utils::convert_columns_string;
|
||||
@ -14,7 +14,7 @@ pub struct GetDF;
|
||||
|
||||
impl Command for GetDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get"
|
||||
"get"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -29,8 +29,8 @@ impl Command for GetDF {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Creates dataframe with selected columns",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr get a",
|
||||
description: "Returns the selected column",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | get a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"a".to_string(),
|
||||
@ -42,6 +42,14 @@ impl Command for GetDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -1,10 +1,9 @@
|
||||
use super::super::values::{utils::DEFAULT_ROWS, Column, NuDataFrame};
|
||||
use crate::dataframe::values::NuExpression;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +11,7 @@ pub struct LastDF;
|
||||
|
||||
impl Command for LastDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr last"
|
||||
"last"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,25 +25,26 @@ impl Command for LastDF {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create new dataframe with last rows",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr last 1",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(3)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(4)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Creates a last expression from a column",
|
||||
example: "dfr col a | dfr last",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
vec![Example {
|
||||
description: "Create new dataframe with last rows",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | last 1",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(3)]),
|
||||
Column::new("b".to_string(), vec![Value::test_int(4)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -54,27 +54,8 @@ impl Command for LastDF {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value = input.into_value(call.head);
|
||||
|
||||
if NuExpression::can_downcast(&value) {
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let expr: NuExpression = expr.into_polars().is_null().into();
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
} else if NuDataFrame::can_downcast(&value) {
|
||||
let df = NuDataFrame::try_from_value(value)?;
|
||||
command(engine_state, stack, call, df)
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or query".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
let df = NuDataFrame::try_from_pipeline(input, call.head)?;
|
||||
command(engine_state, stack, call, df)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ pub struct ListDF;
|
||||
|
||||
impl Command for ListDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr ls"
|
||||
"ls-df"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -25,8 +25,8 @@ impl Command for ListDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Creates a new dataframe and shows it in the dataframe list",
|
||||
example: r#"let test = ([[a b];[1 2] [3 4]] | dfr to-df);
|
||||
dfr ls"#,
|
||||
example: r#"let test = ([[a b];[1 2] [3 4]] | to-df);
|
||||
ls-df"#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type,
|
||||
Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::values::utils::convert_columns_string;
|
||||
@ -14,7 +15,7 @@ pub struct MeltDF;
|
||||
|
||||
impl Command for MeltDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr melt"
|
||||
"melt"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -53,8 +54,7 @@ impl Command for MeltDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "melt dataframe",
|
||||
example:
|
||||
"[[a b c d]; [x 1 4 a] [y 2 5 b] [z 3 6 c]] | dfr to-df | dfr melt -c [b c] -v [a d]",
|
||||
example: "[[a b c d]; [x 1 4 a] [y 2 5 b] [z 3 6 c]] | to-df | melt -c [b c] -v [a d]",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -108,6 +108,14 @@ impl Command for MeltDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -1,6 +1,4 @@
|
||||
mod append;
|
||||
mod column;
|
||||
mod command;
|
||||
mod describe;
|
||||
mod drop;
|
||||
mod drop_duplicates;
|
||||
@ -18,7 +16,6 @@ mod rename;
|
||||
mod sample;
|
||||
mod shape;
|
||||
mod slice;
|
||||
mod sort;
|
||||
mod take;
|
||||
mod to_csv;
|
||||
mod to_df;
|
||||
@ -29,8 +26,6 @@ mod with_column;
|
||||
use nu_protocol::engine::StateWorkingSet;
|
||||
|
||||
pub use append::AppendDF;
|
||||
pub use column::ColumnDF;
|
||||
pub use command::Dataframe;
|
||||
pub use describe::DescribeDF;
|
||||
pub use drop::DropDF;
|
||||
pub use drop_duplicates::DropDuplicates;
|
||||
@ -48,7 +43,6 @@ pub use rename::RenameDF;
|
||||
pub use sample::SampleDF;
|
||||
pub use shape::ShapeDF;
|
||||
pub use slice::SliceDF;
|
||||
pub use sort::SortDF;
|
||||
pub use take::TakeDF;
|
||||
pub use to_csv::ToCSV;
|
||||
pub use to_df::ToDataFrame;
|
||||
@ -69,8 +63,6 @@ pub fn add_eager_decls(working_set: &mut StateWorkingSet) {
|
||||
// Dataframe commands
|
||||
bind_command!(
|
||||
AppendDF,
|
||||
ColumnDF,
|
||||
Dataframe,
|
||||
DataTypes,
|
||||
DescribeDF,
|
||||
DropDF,
|
||||
@ -88,7 +80,6 @@ pub fn add_eager_decls(working_set: &mut StateWorkingSet) {
|
||||
SampleDF,
|
||||
ShapeDF,
|
||||
SliceDF,
|
||||
SortDF,
|
||||
TakeDF,
|
||||
ToCSV,
|
||||
ToDataFrame,
|
||||
|
@ -3,7 +3,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type,
|
||||
};
|
||||
|
||||
use std::{fs::File, io::BufReader, path::PathBuf};
|
||||
@ -15,7 +15,7 @@ pub struct OpenDataFrame;
|
||||
|
||||
impl Command for OpenDataFrame {
|
||||
fn name(&self) -> &str {
|
||||
"dfr open"
|
||||
"open-df"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -64,11 +64,19 @@ impl Command for OpenDataFrame {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Takes a file name and creates a dataframe",
|
||||
example: "dfr open test.csv",
|
||||
example: "open test.csv",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::{utils::extract_strings, values::NuLazyFrame};
|
||||
@ -14,7 +14,7 @@ pub struct RenameDF;
|
||||
|
||||
impl Command for RenameDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr rename-col"
|
||||
"rename"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -33,28 +33,73 @@ impl Command for RenameDF {
|
||||
SyntaxShape::Any,
|
||||
"New names for the selected column(s). A string or list of strings",
|
||||
)
|
||||
.category(Category::Custom("dataframe".into()))
|
||||
.category(Category::Custom("dataframe or lazyframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Renames a dataframe column",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr rename-col a a_new",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a_new".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
vec![
|
||||
Example {
|
||||
description: "Renames a series",
|
||||
example: "[5 6 7 8] | to-df | rename '0' new_name",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"new_name".to_string(),
|
||||
vec![
|
||||
Value::test_int(5),
|
||||
Value::test_int(6),
|
||||
Value::test_int(7),
|
||||
Value::test_int(8),
|
||||
],
|
||||
)])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Renames a dataframe column",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | rename a a_new",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a_new".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Renames two dataframe columns",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | rename [a b] [a_new b_new]",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a_new".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b_new".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -69,16 +114,9 @@ impl Command for RenameDF {
|
||||
if NuLazyFrame::can_downcast(&value) {
|
||||
let df = NuLazyFrame::try_from_value(value)?;
|
||||
command_lazy(engine_state, stack, call, df)
|
||||
} else if NuDataFrame::can_downcast(&value) {
|
||||
} else {
|
||||
let df = NuDataFrame::try_from_value(value)?;
|
||||
command_eager(engine_state, stack, call, df)
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or query".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,7 +171,7 @@ fn command_lazy(
|
||||
let lazy = lazy.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.rename(&columns, &new_names).into();
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type,
|
||||
};
|
||||
|
||||
use super::super::values::NuDataFrame;
|
||||
@ -12,7 +12,7 @@ pub struct SampleDF;
|
||||
|
||||
impl Command for SampleDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr sample"
|
||||
"sample"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -47,17 +47,25 @@ impl Command for SampleDF {
|
||||
vec![
|
||||
Example {
|
||||
description: "Sample rows from dataframe",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr sample -n 1",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | sample -n 1",
|
||||
result: None, // No expected value because sampling is random
|
||||
},
|
||||
Example {
|
||||
description: "Shows sample row using fraction and replace",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | dfr to-df | dfr sample -f 0.5 -e",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | to-df | sample -f 0.5 -e",
|
||||
result: None, // No expected value because sampling is random
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::values::Column;
|
||||
@ -13,7 +13,7 @@ pub struct ShapeDF;
|
||||
|
||||
impl Command for ShapeDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr shape"
|
||||
"shape"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,7 +27,7 @@ impl Command for ShapeDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Shows row and column shape",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr shape",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | shape",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("rows".to_string(), vec![Value::test_int(2)]),
|
||||
@ -39,6 +39,14 @@ impl Command for ShapeDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::values::Column;
|
||||
@ -14,7 +14,7 @@ pub struct SliceDF;
|
||||
|
||||
impl Command for SliceDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr slice"
|
||||
"slice"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -31,7 +31,7 @@ impl Command for SliceDF {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Create new dataframe from a slice of the rows",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr slice 0 1",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | slice 0 1",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)]),
|
||||
@ -43,6 +43,14 @@ impl Command for SliceDF {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -1,148 +0,0 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
};
|
||||
|
||||
use crate::dataframe::values::{utils::convert_columns_string, Column};
|
||||
|
||||
use super::super::values::NuDataFrame;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SortDF;
|
||||
|
||||
impl Command for SortDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr sort"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Creates new sorted dataframe or series"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.switch("reverse", "invert sort", Some('r'))
|
||||
.rest("rest", SyntaxShape::Any, "column names to sort dataframe")
|
||||
.category(Category::Custom("dataframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create new sorted dataframe",
|
||||
example: "[[a b]; [3 4] [1 2]] | dfr to-df | dfr sort a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Create new sorted series",
|
||||
example: "[3 4 1 2] | dfr to-df | dfr sort",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
Value::test_int(4),
|
||||
],
|
||||
)])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
command(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn command(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let reverse = call.has_flag("reverse");
|
||||
|
||||
let df = NuDataFrame::try_from_pipeline(input, call.head)?;
|
||||
|
||||
if df.is_series() {
|
||||
let columns = df.as_ref().get_column_names();
|
||||
|
||||
df.as_ref()
|
||||
.sort(columns, reverse)
|
||||
.map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error sorting dataframe".into(),
|
||||
e.to_string(),
|
||||
Some(call.head),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| PipelineData::Value(NuDataFrame::dataframe_into_value(df, call.head), None))
|
||||
} else {
|
||||
let columns: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
|
||||
if !columns.is_empty() {
|
||||
let (col_string, col_span) = convert_columns_string(columns, call.head)?;
|
||||
|
||||
df.as_ref()
|
||||
.sort(&col_string, reverse)
|
||||
.map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error sorting dataframe".into(),
|
||||
e.to_string(),
|
||||
Some(col_span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| {
|
||||
PipelineData::Value(NuDataFrame::dataframe_into_value(df, call.head), None)
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::GenericError(
|
||||
"Missing columns".into(),
|
||||
"missing column name to perform sort".into(),
|
||||
Some(call.head),
|
||||
None,
|
||||
Vec::new(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(SortDF {})])
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::DataType;
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct TakeDF;
|
||||
|
||||
impl Command for TakeDF {
|
||||
fn name(&self) -> &str {
|
||||
"dfr take"
|
||||
"take"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -36,9 +36,9 @@ impl Command for TakeDF {
|
||||
vec![
|
||||
Example {
|
||||
description: "Takes selected rows from dataframe",
|
||||
example: r#"let df = ([[a b]; [4 1] [5 2] [4 3]] | dfr to-df);
|
||||
let indices = ([0 2] | dfr to-df);
|
||||
$df | dfr take $indices"#,
|
||||
example: r#"let df = ([[a b]; [4 1] [5 2] [4 3]] | to-df);
|
||||
let indices = ([0 2] | to-df);
|
||||
$df | take $indices"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -56,9 +56,9 @@ impl Command for TakeDF {
|
||||
},
|
||||
Example {
|
||||
description: "Takes selected rows from series",
|
||||
example: r#"let series = ([4 1 5 2 4 3] | dfr to-df);
|
||||
let indices = ([0 2] | dfr to-df);
|
||||
$series | dfr take $indices"#,
|
||||
example: r#"let series = ([4 1 5 2 4 3] | to-df);
|
||||
let indices = ([0 2] | to-df);
|
||||
$series | take $indices"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -71,6 +71,14 @@ impl Command for TakeDF {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::{CsvWriter, SerWriter};
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct ToCSV;
|
||||
|
||||
impl Command for ToCSV {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-csv"
|
||||
"to-csv"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -39,17 +39,25 @@ impl Command for ToCSV {
|
||||
vec![
|
||||
Example {
|
||||
description: "Saves dataframe to csv file",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-csv test.csv",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | to-csv test.csv",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Saves dataframe to csv file using other delimiter",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-csv test.csv -d '|'",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | to-csv test.csv -d '|'",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct ToDataFrame;
|
||||
|
||||
impl Command for ToDataFrame {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-df"
|
||||
"to-df"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for ToDataFrame {
|
||||
vec![
|
||||
Example {
|
||||
description: "Takes a dictionary and creates a dataframe",
|
||||
example: "[[a b];[1 2] [3 4]] | dfr to-df",
|
||||
example: "[[a b];[1 2] [3 4]] | to-df",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -44,7 +44,7 @@ impl Command for ToDataFrame {
|
||||
},
|
||||
Example {
|
||||
description: "Takes a list of tables and creates a dataframe",
|
||||
example: "[[1 2 a] [3 4 b] [5 6 c]] | dfr to-df",
|
||||
example: "[[1 2 a] [3 4 b] [5 6 c]] | to-df",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -70,7 +70,7 @@ impl Command for ToDataFrame {
|
||||
},
|
||||
Example {
|
||||
description: "Takes a list and creates a dataframe",
|
||||
example: "[a b c] | dfr to-df",
|
||||
example: "[a b c] | to-df",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -86,7 +86,7 @@ impl Command for ToDataFrame {
|
||||
},
|
||||
Example {
|
||||
description: "Takes a list of booleans and creates a dataframe",
|
||||
example: "[true true false] | dfr to-df",
|
||||
example: "[true true false] | to-df",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -103,6 +103,14 @@ impl Command for ToDataFrame {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use super::super::values::NuDataFrame;
|
||||
@ -12,7 +12,7 @@ pub struct ToNu;
|
||||
|
||||
impl Command for ToNu {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-nu"
|
||||
"to-nu"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -22,7 +22,7 @@ impl Command for ToNu {
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.named(
|
||||
"n-rows",
|
||||
"rows",
|
||||
SyntaxShape::Number,
|
||||
"number of rows to be shown",
|
||||
Some('n'),
|
||||
@ -35,17 +35,25 @@ impl Command for ToNu {
|
||||
vec![
|
||||
Example {
|
||||
description: "Shows head rows from dataframe",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-nu",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | to nu",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Shows tail rows from dataframe",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | dfr to-df | dfr to-nu -t -n 1",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | to-df | to nu -t -n 1",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::ParquetWriter;
|
||||
|
||||
@ -15,7 +15,7 @@ pub struct ToParquet;
|
||||
|
||||
impl Command for ToParquet {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-parquet"
|
||||
"to-parquet"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -30,12 +30,20 @@ impl Command for ToParquet {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Saves dataframe to csv file",
|
||||
example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-parquet test.parquet",
|
||||
description: "Saves dataframe to parquet file",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-df | to-parquet test.parquet",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +12,7 @@ pub struct WithColumn;
|
||||
|
||||
impl Command for WithColumn {
|
||||
fn name(&self) -> &str {
|
||||
"dfr with-column"
|
||||
"with-column"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,16 +27,16 @@ impl Command for WithColumn {
|
||||
SyntaxShape::Any,
|
||||
"series to be added or expressions used to define the new columns",
|
||||
)
|
||||
.category(Category::Custom("dataframe".into()))
|
||||
.category(Category::Custom("dataframe or lazyframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Adds a series to the dataframe",
|
||||
example: r#"[[a b]; [1 2] [3 4]]
|
||||
| dfr to-df
|
||||
| dfr with-column ([5 6] | dfr to-df) --name c"#,
|
||||
example: r#"[[a b]; [1 2] [3 4]]
|
||||
| to-df
|
||||
| with-column ([5 6] | to-df) --name c"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
@ -58,16 +58,47 @@ impl Command for WithColumn {
|
||||
},
|
||||
Example {
|
||||
description: "Adds a series to the dataframe",
|
||||
example: r#"[[a b]; [1 2] [3 4]]
|
||||
| dfr to-df
|
||||
| dfr to-lazy
|
||||
| dfr with-column ((dfr col a) * 2 | dfr as "c")
|
||||
| dfr collect"#,
|
||||
result: None,
|
||||
example: r#"[[a b]; [1 2] [3 4]]
|
||||
| to-lazy
|
||||
| with-column [
|
||||
((col a) * 2 | as "c")
|
||||
((col a) * 3 | as "d")
|
||||
]
|
||||
| collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"c".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"d".to_string(),
|
||||
vec![Value::test_int(3), Value::test_int(9)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -85,7 +116,7 @@ impl Command for WithColumn {
|
||||
command_eager(engine_state, stack, call, df)
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or query".into(),
|
||||
"lazy or eager dataframe".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
@ -100,34 +131,49 @@ fn command_eager(
|
||||
call: &Call,
|
||||
mut df: NuDataFrame,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let other_value: Value = call.req(engine_state, stack, 0)?;
|
||||
let other_span = other_value.span()?;
|
||||
let mut other = NuDataFrame::try_from_value(other_value)?.as_series(other_span)?;
|
||||
let new_column: Value = call.req(engine_state, stack, 0)?;
|
||||
let column_span = new_column.span()?;
|
||||
|
||||
let name = match call.get_flag::<String>(engine_state, stack, "name")? {
|
||||
Some(name) => name,
|
||||
None => other.name().to_string(),
|
||||
};
|
||||
if NuExpression::can_downcast(&new_column) {
|
||||
let vals: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let value = Value::List {
|
||||
vals,
|
||||
span: call.head,
|
||||
};
|
||||
let expressions = NuExpression::extract_exprs(value)?;
|
||||
let lazy = NuLazyFrame::new(true, df.lazy().with_columns(&expressions));
|
||||
|
||||
let series = other.rename(&name).clone();
|
||||
let df = lazy.collect(call.head)?;
|
||||
|
||||
df.as_mut()
|
||||
.with_column(series)
|
||||
.map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error adding column to dataframe".into(),
|
||||
e.to_string(),
|
||||
Some(other_span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| {
|
||||
PipelineData::Value(
|
||||
NuDataFrame::dataframe_into_value(df.clone(), call.head),
|
||||
None,
|
||||
)
|
||||
})
|
||||
Ok(PipelineData::Value(df.into_value(call.head), None))
|
||||
} else {
|
||||
let mut other = NuDataFrame::try_from_value(new_column)?.as_series(column_span)?;
|
||||
|
||||
let name = match call.get_flag::<String>(engine_state, stack, "name")? {
|
||||
Some(name) => name,
|
||||
None => other.name().to_string(),
|
||||
};
|
||||
|
||||
let series = other.rename(&name).clone();
|
||||
|
||||
df.as_mut()
|
||||
.with_column(series)
|
||||
.map_err(|e| {
|
||||
ShellError::GenericError(
|
||||
"Error adding column to dataframe".into(),
|
||||
e.to_string(),
|
||||
Some(column_span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
})
|
||||
.map(|df| {
|
||||
PipelineData::Value(
|
||||
NuDataFrame::dataframe_into_value(df.clone(), call.head),
|
||||
None,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn command_lazy(
|
||||
@ -146,7 +192,7 @@ fn command_lazy(
|
||||
let lazy: NuLazyFrame = lazy.into_polars().with_columns(&expressions).into();
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuLazyFrame::into_value(lazy, call.head),
|
||||
NuLazyFrame::into_value(lazy, call.head)?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
@ -155,9 +201,15 @@ fn command_lazy(
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::ExprAlias;
|
||||
use crate::dataframe::expressions::ExprCol;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(WithColumn {})])
|
||||
test_dataframe(vec![
|
||||
Box::new(WithColumn {}),
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprCol {}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +12,7 @@ pub struct ExprAlias;
|
||||
|
||||
impl Command for ExprAlias {
|
||||
fn name(&self) -> &str {
|
||||
"dfr as"
|
||||
"as"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,17 +26,45 @@ impl Command for ExprAlias {
|
||||
SyntaxShape::String,
|
||||
"Alias name for the expression",
|
||||
)
|
||||
.category(Category::Custom("expressions".into()))
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Creates and alias expression",
|
||||
example: "(dfr col a | df as new_a)",
|
||||
result: None,
|
||||
example: "col a | as new_a | to-nu",
|
||||
result: {
|
||||
let cols = vec!["expr".into(), "value".into()];
|
||||
let expr = Value::test_string("column");
|
||||
let value = Value::test_string("a");
|
||||
let expr = Value::Record {
|
||||
cols,
|
||||
vals: vec![expr, value],
|
||||
span: Span::test_data(),
|
||||
};
|
||||
|
||||
let cols = vec!["expr".into(), "alias".into()];
|
||||
let value = Value::test_string("new_a");
|
||||
|
||||
let record = Value::Record {
|
||||
cols,
|
||||
vals: vec![expr, value],
|
||||
span: Span::test_data(),
|
||||
};
|
||||
|
||||
Some(record)
|
||||
},
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -55,3 +83,20 @@ impl Command for ExprAlias {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::ExprAsNu;
|
||||
use crate::dataframe::expressions::ExprCol;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprCol {}),
|
||||
Box::new(ExprAsNu {}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,15 @@ use super::super::values::NuExpression;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExprToNu;
|
||||
pub struct ExprAsNu;
|
||||
|
||||
impl Command for ExprToNu {
|
||||
impl Command for ExprAsNu {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-nu"
|
||||
"to-nu"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -19,13 +19,13 @@ impl Command for ExprToNu {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).category(Category::Custom("expressions".into()))
|
||||
Signature::build(self.name()).category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Convert a col expression into a nushell value",
|
||||
example: "dfr col col_a | dfr to-nu",
|
||||
example: "col a | to-nu",
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["expr".into(), "value".into()],
|
||||
vals: vec![
|
||||
@ -34,7 +34,7 @@ impl Command for ExprToNu {
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::String {
|
||||
val: "col_a".into(),
|
||||
val: "a".into(),
|
||||
span: Span::test_data(),
|
||||
},
|
||||
],
|
||||
@ -43,6 +43,14 @@ impl Command for ExprToNu {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
@ -65,6 +73,6 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(ExprToNu {}), Box::new(ExprCol {})])
|
||||
test_dataframe(vec![Box::new(ExprAsNu {}), Box::new(ExprCol {})])
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::col;
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ExprCol;
|
||||
|
||||
impl Command for ExprCol {
|
||||
fn name(&self) -> &str {
|
||||
"dfr col"
|
||||
"col"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,13 +26,13 @@ impl Command for ExprCol {
|
||||
SyntaxShape::String,
|
||||
"Name of column to be used",
|
||||
)
|
||||
.category(Category::Custom("expressions".into()))
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Creates a named column expression and converts it to a nu object",
|
||||
example: "dfr col col_a | dfr to-nu",
|
||||
example: "col a | to-nu",
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["expr".into(), "value".into()],
|
||||
vals: vec![
|
||||
@ -41,7 +41,7 @@ impl Command for ExprCol {
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::String {
|
||||
val: "col_a".into(),
|
||||
val: "a".into(),
|
||||
span: Span::test_data(),
|
||||
},
|
||||
],
|
||||
@ -50,6 +50,14 @@ impl Command for ExprCol {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -66,12 +74,12 @@ impl Command for ExprCol {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::super::test_dataframe::test_dataframe;
|
||||
use super::super::super::ExprToNu;
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::as_nu::ExprAsNu;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(ExprCol {}), Box::new(ExprToNu {})])
|
||||
test_dataframe(vec![Box::new(ExprCol {}), Box::new(ExprAsNu {})])
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
mod col;
|
||||
mod lit;
|
||||
mod when;
|
||||
|
||||
pub(super) use crate::dataframe::expressions::dsl::col::ExprCol;
|
||||
pub(super) use crate::dataframe::expressions::dsl::lit::ExprLit;
|
||||
pub(super) use crate::dataframe::expressions::dsl::when::ExprWhen;
|
@ -1,96 +0,0 @@
|
||||
use crate::dataframe::values::NuExpression;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
};
|
||||
use polars::prelude::when;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExprWhen;
|
||||
|
||||
impl Command for ExprWhen {
|
||||
fn name(&self) -> &str {
|
||||
"dfr when"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Creates a when expression"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
"when predicate",
|
||||
SyntaxShape::Any,
|
||||
"Name of column to be used",
|
||||
)
|
||||
.required_named(
|
||||
"then",
|
||||
SyntaxShape::Any,
|
||||
"Expression that will be applied when predicate is true",
|
||||
Some('t'),
|
||||
)
|
||||
.required_named(
|
||||
"otherwise",
|
||||
SyntaxShape::Any,
|
||||
"Expression that will be applied when predicate is false",
|
||||
Some('o'),
|
||||
)
|
||||
.category(Category::Custom("expressions".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Create a new column for the dataframe",
|
||||
example: r#"[[a b]; [1 2] [3 4]]
|
||||
| dfr to-df
|
||||
| dfr to-lazy
|
||||
| dfr with-column (
|
||||
dfr when ((dfr col a) > 2) --then 4 --otherwise 5 | dfr as "c"
|
||||
)
|
||||
| dfr collect"#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let predicate: Value = call.req(engine_state, stack, 0)?;
|
||||
let predicate = NuExpression::try_from_value(predicate)?;
|
||||
|
||||
let then: Value = call
|
||||
.get_flag(engine_state, stack, "then")?
|
||||
.expect("it is a required named value");
|
||||
let then = NuExpression::try_from_value(then)?;
|
||||
let otherwise: Value = call
|
||||
.get_flag(engine_state, stack, "otherwise")?
|
||||
.expect("it is a required named value");
|
||||
let otherwise = NuExpression::try_from_value(otherwise)?;
|
||||
|
||||
let expr: NuExpression = when(predicate.into_polars())
|
||||
.then(then.into_polars())
|
||||
.otherwise(otherwise.into_polars())
|
||||
.into();
|
||||
|
||||
Ok(PipelineData::Value(expr.into_value(call.head), None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::super::test_dataframe::test_dataframe;
|
||||
use super::super::super::ExprToNu;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(ExprWhen {}), Box::new(ExprToNu {})])
|
||||
}
|
||||
}
|
@ -1,18 +1,17 @@
|
||||
/// Definition of multiple Expression commands using a macro rule
|
||||
/// All of these expressions have an identical body and only require
|
||||
/// to have a change in the name, description and expression function
|
||||
use super::super::values::NuExpression;
|
||||
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
// The structs defined in this file are structs that form part of other commands
|
||||
// since they share a similar name
|
||||
macro_rules! expr_command {
|
||||
($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident) => {
|
||||
($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident, $test: ident) => {
|
||||
#[derive(Clone)]
|
||||
pub struct $command;
|
||||
|
||||
@ -26,13 +25,21 @@ macro_rules! expr_command {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).category(Category::Custom("dataframe".into()))
|
||||
Signature::build(self.name()).category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
$examples
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
@ -49,6 +56,23 @@ macro_rules! expr_command {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod $test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::lazy::aggregate::LazyAggregate;
|
||||
use crate::dataframe::lazy::groupby::ToLazyGroupBy;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new($command {}),
|
||||
Box::new(LazyAggregate {}),
|
||||
Box::new(ToLazyGroupBy {}),
|
||||
])
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -56,54 +80,380 @@ macro_rules! expr_command {
|
||||
// Expands to a command definition for a list expression
|
||||
expr_command!(
|
||||
ExprList,
|
||||
"dfr list",
|
||||
"list",
|
||||
"Aggregates a group to a Series",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
list
|
||||
list,
|
||||
test_list
|
||||
);
|
||||
|
||||
// ExprAggGroups command
|
||||
// Expands to a command definition for a agg groups expression
|
||||
expr_command!(
|
||||
ExprAggGroups,
|
||||
"dfr agg-groups",
|
||||
"agg-groups",
|
||||
"creates an agg_groups expression",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
agg_groups
|
||||
agg_groups,
|
||||
test_groups
|
||||
);
|
||||
|
||||
// ExprFlatten command
|
||||
// Expands to a command definition for a flatten expression
|
||||
expr_command!(
|
||||
ExprFlatten,
|
||||
"dfr flatten",
|
||||
"flatten",
|
||||
"creates a flatten expression",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
flatten
|
||||
flatten,
|
||||
test_flatten
|
||||
);
|
||||
|
||||
// ExprExplode command
|
||||
// Expands to a command definition for a explode expression
|
||||
expr_command!(
|
||||
ExprExplode,
|
||||
"dfr explode",
|
||||
"explode",
|
||||
"creates an explode expression",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
explode
|
||||
explode,
|
||||
test_explode
|
||||
);
|
||||
|
||||
// ExprCount command
|
||||
// Expands to a command definition for a count expression
|
||||
expr_command!(
|
||||
ExprCount,
|
||||
"count",
|
||||
"creates a count expression",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
count,
|
||||
test_count
|
||||
);
|
||||
|
||||
// ExprFirst command
|
||||
// Expands to a command definition for a count expression
|
||||
expr_command!(
|
||||
ExprFirst,
|
||||
"first",
|
||||
"creates a first expression",
|
||||
vec![Example {
|
||||
description: "Creates a first expression from a column",
|
||||
example: "col a | first",
|
||||
result: None,
|
||||
},],
|
||||
first,
|
||||
test_first
|
||||
);
|
||||
|
||||
// ExprLast command
|
||||
// Expands to a command definition for a count expression
|
||||
expr_command!(
|
||||
ExprLast,
|
||||
"last",
|
||||
"creates a last expression",
|
||||
vec![Example {
|
||||
description: "Creates a last expression from a column",
|
||||
example: "col a | last",
|
||||
result: None,
|
||||
},],
|
||||
last,
|
||||
test_last
|
||||
);
|
||||
|
||||
// ExprNUnique command
|
||||
// Expands to a command definition for a n-unique expression
|
||||
expr_command!(
|
||||
ExprNUnique,
|
||||
"n-unique",
|
||||
"creates a n-unique expression",
|
||||
vec![Example {
|
||||
description: "Creates a is n-unique expression from a column",
|
||||
example: "col a | n-unique",
|
||||
result: None,
|
||||
},],
|
||||
n_unique,
|
||||
test_nunique
|
||||
);
|
||||
|
||||
// ExprIsNotNull command
|
||||
// Expands to a command definition for a n-unique expression
|
||||
expr_command!(
|
||||
ExprIsNotNull,
|
||||
"is-not-null",
|
||||
"creates a is not null expression",
|
||||
vec![Example {
|
||||
description: "Creates a is not null expression from a column",
|
||||
example: "col a | is-not-null",
|
||||
result: None,
|
||||
},],
|
||||
is_not_null,
|
||||
test_is_not_null
|
||||
);
|
||||
|
||||
// ExprIsNull command
|
||||
// Expands to a command definition for a n-unique expression
|
||||
expr_command!(
|
||||
ExprIsNull,
|
||||
"is-null",
|
||||
"creates a is null expression",
|
||||
vec![Example {
|
||||
description: "Creates a is null expression from a column",
|
||||
example: "col a | is-null",
|
||||
result: None,
|
||||
},],
|
||||
is_null,
|
||||
test_is_null
|
||||
);
|
||||
|
||||
// ExprNot command
|
||||
// Expands to a command definition for a not expression
|
||||
expr_command!(
|
||||
ExprNot,
|
||||
"expr-not",
|
||||
"creates a not expression",
|
||||
vec![Example {
|
||||
description: "Creates a not expression",
|
||||
example: "(col a) > 2) | expr-not",
|
||||
result: None,
|
||||
},],
|
||||
not,
|
||||
test_not
|
||||
);
|
||||
|
||||
// ExprMax command
|
||||
// Expands to a command definition for max aggregation
|
||||
expr_command!(
|
||||
ExprMax,
|
||||
"max",
|
||||
"Creates a max expression",
|
||||
vec![Example {
|
||||
description: "Max aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | max)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(1)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
max,
|
||||
test_max
|
||||
);
|
||||
|
||||
// ExprMin command
|
||||
// Expands to a command definition for min aggregation
|
||||
expr_command!(
|
||||
ExprMin,
|
||||
"min",
|
||||
"Creates a min expression",
|
||||
vec![Example {
|
||||
description: "Min aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | min)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(1)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
min,
|
||||
test_min
|
||||
);
|
||||
|
||||
// ExprSum command
|
||||
// Expands to a command definition for sum aggregation
|
||||
expr_command!(
|
||||
ExprSum,
|
||||
"sum",
|
||||
"Creates a sum expression for an aggregation",
|
||||
vec![Example {
|
||||
description: "Sum aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | sum)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(1)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
sum,
|
||||
test_sum
|
||||
);
|
||||
|
||||
// ExprMean command
|
||||
// Expands to a command definition for mean aggregation
|
||||
expr_command!(
|
||||
ExprMean,
|
||||
"mean",
|
||||
"Creates a mean expression for an aggregation",
|
||||
vec![Example {
|
||||
description: "Mean aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | mean)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_float(3.0), Value::test_float(1.0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
mean,
|
||||
test_mean
|
||||
);
|
||||
|
||||
// ExprMedian command
|
||||
// Expands to a command definition for median aggregation
|
||||
expr_command!(
|
||||
ExprMedian,
|
||||
"median",
|
||||
"Creates a median expression for an aggregation",
|
||||
vec![Example {
|
||||
description: "Median aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | median)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_float(3.0), Value::test_float(1.0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
median,
|
||||
test_median
|
||||
);
|
||||
|
||||
// ExprStd command
|
||||
// Expands to a command definition for std aggregation
|
||||
expr_command!(
|
||||
ExprStd,
|
||||
"std",
|
||||
"Creates a std expression for an aggregation",
|
||||
vec![Example {
|
||||
description: "Std aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | std)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_float(0.0), Value::test_float(0.0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
std,
|
||||
test_std
|
||||
);
|
||||
|
||||
// ExprVar command
|
||||
// Expands to a command definition for var aggregation
|
||||
expr_command!(
|
||||
ExprVar,
|
||||
"var",
|
||||
"Create a var expression for an aggregation",
|
||||
vec![Example {
|
||||
description: "Var aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | var)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_float(0.0), Value::test_float(0.0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
var,
|
||||
test_var
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct ExprLit;
|
||||
|
||||
impl Command for ExprLit {
|
||||
fn name(&self) -> &str {
|
||||
"dfr lit"
|
||||
"lit"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -25,13 +25,13 @@ impl Command for ExprLit {
|
||||
SyntaxShape::Any,
|
||||
"literal to construct the expression",
|
||||
)
|
||||
.category(Category::Custom("expressions".into()))
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Created a literal expression and converts it to a nu object",
|
||||
example: "dfr lit 2 | dfr to-nu",
|
||||
example: "lit 2 | to-nu",
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["expr".into(), "value".into()],
|
||||
vals: vec![
|
||||
@ -49,6 +49,14 @@ impl Command for ExprLit {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -68,12 +76,12 @@ impl Command for ExprLit {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::super::test_dataframe::test_dataframe;
|
||||
use super::super::super::ExprToNu;
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::as_nu::ExprAsNu;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(ExprLit {}), Box::new(ExprToNu {})])
|
||||
test_dataframe(vec![Box::new(ExprLit {}), Box::new(ExprAsNu {})])
|
||||
}
|
||||
}
|
@ -1,15 +1,22 @@
|
||||
mod alias;
|
||||
mod dsl;
|
||||
mod as_nu;
|
||||
mod col;
|
||||
mod expressions_macro;
|
||||
mod to_nu;
|
||||
mod lit;
|
||||
mod otherwise;
|
||||
mod quantile;
|
||||
mod when;
|
||||
|
||||
use nu_protocol::engine::StateWorkingSet;
|
||||
|
||||
use crate::dataframe::expressions::dsl::*;
|
||||
|
||||
use crate::dataframe::expressions::alias::ExprAlias;
|
||||
use crate::dataframe::expressions::expressions_macro::*;
|
||||
use crate::dataframe::expressions::to_nu::ExprToNu;
|
||||
pub(crate) use crate::dataframe::expressions::alias::ExprAlias;
|
||||
use crate::dataframe::expressions::as_nu::ExprAsNu;
|
||||
pub(super) use crate::dataframe::expressions::col::ExprCol;
|
||||
pub(crate) use crate::dataframe::expressions::expressions_macro::*;
|
||||
pub(super) use crate::dataframe::expressions::lit::ExprLit;
|
||||
pub(super) use crate::dataframe::expressions::otherwise::ExprOtherwise;
|
||||
pub(super) use crate::dataframe::expressions::quantile::ExprQuantile;
|
||||
pub(super) use crate::dataframe::expressions::when::ExprWhen;
|
||||
|
||||
pub fn add_expressions(working_set: &mut StateWorkingSet) {
|
||||
macro_rules! bind_command {
|
||||
@ -25,12 +32,29 @@ pub fn add_expressions(working_set: &mut StateWorkingSet) {
|
||||
bind_command!(
|
||||
ExprAlias,
|
||||
ExprCol,
|
||||
ExprCount,
|
||||
ExprLit,
|
||||
ExprToNu,
|
||||
ExprAsNu,
|
||||
ExprWhen,
|
||||
ExprOtherwise,
|
||||
ExprQuantile,
|
||||
ExprList,
|
||||
ExprAggGroups,
|
||||
ExprFlatten,
|
||||
ExprExplode
|
||||
ExprExplode,
|
||||
ExprCount,
|
||||
ExprFirst,
|
||||
ExprLast,
|
||||
ExprNUnique,
|
||||
ExprIsNotNull,
|
||||
ExprIsNull,
|
||||
ExprNot,
|
||||
ExprMax,
|
||||
ExprMin,
|
||||
ExprSum,
|
||||
ExprMean,
|
||||
ExprMedian,
|
||||
ExprStd,
|
||||
ExprVar
|
||||
);
|
||||
}
|
||||
|
132
crates/nu-command/src/dataframe/expressions/otherwise.rs
Normal file
132
crates/nu-command/src/dataframe/expressions/otherwise.rs
Normal file
@ -0,0 +1,132 @@
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuWhen};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExprOtherwise;
|
||||
|
||||
impl Command for ExprOtherwise {
|
||||
fn name(&self) -> &str {
|
||||
"otherwise"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"completes a when expression"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
"otherwise expression",
|
||||
SyntaxShape::Any,
|
||||
"expressioini to apply when no when predicate matches",
|
||||
)
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create a when conditions",
|
||||
example: "when ((col a) > 2) 4 | otherwise 5",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Create a when conditions",
|
||||
example: "when ((col a) > 2) 4 | when ((col a) < 0) 6 | otherwise 0",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Create a new column for the dataframe",
|
||||
example: r#"[[a b]; [6 2] [1 4] [4 1]]
|
||||
| to-lazy
|
||||
| with-column (
|
||||
when ((col a) > 2) 4 | otherwise 5 | as c
|
||||
)
|
||||
| with-column (
|
||||
when ((col a) > 5) 10 | when ((col a) < 2) 6 | otherwise 0 | as d
|
||||
)
|
||||
| collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(1), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4), Value::test_int(1)],
|
||||
),
|
||||
Column::new(
|
||||
"c".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(5), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"d".to_string(),
|
||||
vec![Value::test_int(10), Value::test_int(6), Value::test_int(0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let otherwise_predicate: Value = call.req(engine_state, stack, 0)?;
|
||||
let otherwise_predicate = NuExpression::try_from_value(otherwise_predicate)?;
|
||||
|
||||
let value = input.into_value(call.head);
|
||||
let complete: NuExpression = match NuWhen::try_from_value(value)? {
|
||||
NuWhen::WhenThen(when_then) => when_then
|
||||
.otherwise(otherwise_predicate.into_polars())
|
||||
.into(),
|
||||
NuWhen::WhenThenThen(when_then_then) => when_then_then
|
||||
.otherwise(otherwise_predicate.into_polars())
|
||||
.into(),
|
||||
};
|
||||
|
||||
Ok(PipelineData::Value(complete.into_value(call.head), None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use crate::dataframe::eager::WithColumn;
|
||||
use crate::dataframe::expressions::when::ExprWhen;
|
||||
use crate::dataframe::expressions::{ExprAlias, ExprAsNu, ExprCol};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(WithColumn {}),
|
||||
Box::new(ExprCol {}),
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprWhen {}),
|
||||
Box::new(ExprOtherwise {}),
|
||||
Box::new(ExprAsNu {}),
|
||||
])
|
||||
}
|
||||
}
|
102
crates/nu-command/src/dataframe/expressions/quantile.rs
Normal file
102
crates/nu-command/src/dataframe/expressions/quantile.rs
Normal file
@ -0,0 +1,102 @@
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::QuantileInterpolOptions;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExprQuantile;
|
||||
|
||||
impl Command for ExprQuantile {
|
||||
fn name(&self) -> &str {
|
||||
"quantile"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Aggregates the columns to the selected quantile"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
"quantile",
|
||||
SyntaxShape::Number,
|
||||
"quantile value for quantile operation",
|
||||
)
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Quantile aggregation for a group by",
|
||||
example: r#"[[a b]; [one 2] [one 4] [two 1]]
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg (col b | quantile 0.5)"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_string("one"), Value::test_string("two")],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_float(4.0), Value::test_float(1.0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value = input.into_value(call.head);
|
||||
let quantile: f64 = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let expr: NuExpression = expr
|
||||
.into_polars()
|
||||
.quantile(quantile, QuantileInterpolOptions::default())
|
||||
.into();
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::lazy::aggregate::LazyAggregate;
|
||||
use crate::dataframe::lazy::groupby::ToLazyGroupBy;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(ExprQuantile {}),
|
||||
Box::new(LazyAggregate {}),
|
||||
Box::new(ToLazyGroupBy {}),
|
||||
])
|
||||
}
|
||||
}
|
148
crates/nu-command/src/dataframe/expressions/when.rs
Normal file
148
crates/nu-command/src/dataframe/expressions/when.rs
Normal file
@ -0,0 +1,148 @@
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuWhen};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::when;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExprWhen;
|
||||
|
||||
impl Command for ExprWhen {
|
||||
fn name(&self) -> &str {
|
||||
"when"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Creates and modifies a when expression"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
"when expression",
|
||||
SyntaxShape::Any,
|
||||
"when expression used for matching",
|
||||
)
|
||||
.required(
|
||||
"then expression",
|
||||
SyntaxShape::Any,
|
||||
"expression that will be applied when predicate is true",
|
||||
)
|
||||
.category(Category::Custom("expression".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Create a when conditions",
|
||||
example: "when ((col a) > 2) 4",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Create a when conditions",
|
||||
example: "when ((col a) > 2) 4 | when ((col a) < 0) 6",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Create a new column for the dataframe",
|
||||
example: r#"[[a b]; [6 2] [1 4] [4 1]]
|
||||
| to-lazy
|
||||
| with-column (
|
||||
when ((col a) > 2) 4 | otherwise 5 | as c
|
||||
)
|
||||
| with-column (
|
||||
when ((col a) > 5) 10 | when ((col a) < 2) 6 | otherwise 0 | as d
|
||||
)
|
||||
| collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(1), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4), Value::test_int(1)],
|
||||
),
|
||||
Column::new(
|
||||
"c".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(5), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"d".to_string(),
|
||||
vec![Value::test_int(10), Value::test_int(6), Value::test_int(0)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("expression".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let when_predicate: Value = call.req(engine_state, stack, 0)?;
|
||||
let when_predicate = NuExpression::try_from_value(when_predicate)?;
|
||||
|
||||
let then_predicate: Value = call.req(engine_state, stack, 1)?;
|
||||
let then_predicate = NuExpression::try_from_value(then_predicate)?;
|
||||
|
||||
let value = input.into_value(call.head);
|
||||
let when_then: NuWhen = match value {
|
||||
Value::Nothing { .. } => when(when_predicate.into_polars())
|
||||
.then(then_predicate.into_polars())
|
||||
.into(),
|
||||
v => match NuWhen::try_from_value(v)? {
|
||||
NuWhen::WhenThen(when_then) => when_then
|
||||
.when(when_predicate.into_polars())
|
||||
.then(then_predicate.into_polars())
|
||||
.into(),
|
||||
NuWhen::WhenThenThen(when_then_then) => when_then_then
|
||||
.when(when_predicate.into_polars())
|
||||
.then(then_predicate.into_polars())
|
||||
.into(),
|
||||
},
|
||||
};
|
||||
|
||||
Ok(PipelineData::Value(when_then.into_value(call.head), None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use crate::dataframe::eager::WithColumn;
|
||||
use crate::dataframe::expressions::otherwise::ExprOtherwise;
|
||||
use crate::dataframe::expressions::{ExprAlias, ExprAsNu, ExprCol};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(WithColumn {}),
|
||||
Box::new(ExprCol {}),
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprWhen {}),
|
||||
Box::new(ExprOtherwise {}),
|
||||
Box::new(ExprAsNu {}),
|
||||
])
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame, NuLazyGroupBy};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame, NuLazyGroupBy};
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +12,7 @@ pub struct LazyAggregate;
|
||||
|
||||
impl Command for LazyAggregate {
|
||||
fn name(&self) -> &str {
|
||||
"dfr aggregate"
|
||||
"agg"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -34,32 +34,81 @@ impl Command for LazyAggregate {
|
||||
Example {
|
||||
description: "Group by and perform an aggregation",
|
||||
example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]]
|
||||
| dfr to-df
|
||||
| dfr group-by a
|
||||
| dfr aggregate [
|
||||
("b" | dfr min | dfr as "b_min")
|
||||
("b" | dfr max | dfr as "b_max")
|
||||
("b" | dfr sum | dfr as "b_sum")
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg [
|
||||
(col b | min | as "b_min")
|
||||
(col b | max | as "b_max")
|
||||
(col b | sum | as "b_sum")
|
||||
]"#,
|
||||
result: None,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
),
|
||||
Column::new(
|
||||
"b_min".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b_max".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"b_sum".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(10)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Group by and perform an aggregation",
|
||||
example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]]
|
||||
| dfr to-df
|
||||
| dfr to-lazy
|
||||
| dfr group-by a
|
||||
| dfr aggregate [
|
||||
("b" | dfr min | dfr as "b_min")
|
||||
("b" | dfr max | dfr as "b_max")
|
||||
("b" | dfr sum | dfr as "b_sum")
|
||||
| to-lazy
|
||||
| group-by a
|
||||
| agg [
|
||||
(col b | min | as "b_min")
|
||||
(col b | max | as "b_max")
|
||||
(col b | sum | as "b_sum")
|
||||
]
|
||||
| dfr collect"#,
|
||||
result: None,
|
||||
| collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
),
|
||||
Column::new(
|
||||
"b_min".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b_max".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"b_sum".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(10)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -78,14 +127,32 @@ impl Command for LazyAggregate {
|
||||
let from_eager = group_by.from_eager;
|
||||
|
||||
let group_by = group_by.into_polars();
|
||||
let lazy: NuLazyFrame = group_by.agg(&expressions).into();
|
||||
|
||||
let res = if from_eager {
|
||||
lazy.collect(call.head)?.into_value(call.head)
|
||||
} else {
|
||||
lazy.into_value(call.head)
|
||||
let lazy = NuLazyFrame {
|
||||
lazy: group_by.agg(&expressions).into(),
|
||||
from_eager,
|
||||
};
|
||||
|
||||
let res = lazy.into_value(call.head)?;
|
||||
Ok(PipelineData::Value(res, None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::{ExprAlias, ExprMax, ExprMin, ExprSum};
|
||||
use crate::dataframe::lazy::groupby::ToLazyGroupBy;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(LazyAggregate {}),
|
||||
Box::new(ToLazyGroupBy {}),
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprMin {}),
|
||||
Box::new(ExprMax {}),
|
||||
Box::new(ExprSum {}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use super::super::values::{NuDataFrame, NuLazyFrame};
|
||||
use crate::dataframe::values::{Column, NuDataFrame};
|
||||
|
||||
use super::super::values::NuLazyFrame;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,11 +12,11 @@ pub struct LazyCollect;
|
||||
|
||||
impl Command for LazyCollect {
|
||||
fn name(&self) -> &str {
|
||||
"dfr collect"
|
||||
"collect"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Collect lazy dataframe into dataframe"
|
||||
"Collect lazy dataframe into eager dataframe"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
@ -24,12 +25,33 @@ impl Command for LazyCollect {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
description: "drop duplicates",
|
||||
example: "[[a b]; [1 2] [3 4]] | to-lazy | collect",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(3)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
@ -39,10 +61,22 @@ impl Command for LazyCollect {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?;
|
||||
let eager = lazy.collect(call.head)?;
|
||||
let value = Value::CustomValue {
|
||||
val: Box::new(eager),
|
||||
span: call.head,
|
||||
};
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuDataFrame::into_value(eager, call.head),
|
||||
None,
|
||||
))
|
||||
Ok(PipelineData::Value(value, None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazyCollect {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use super::super::values::NuLazyFrame;
|
||||
use crate::dataframe::values::NuDataFrame;
|
||||
use crate::dataframe::values::{Column, NuDataFrame};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +12,7 @@ pub struct LazyFetch;
|
||||
|
||||
impl Command for LazyFetch {
|
||||
fn name(&self) -> &str {
|
||||
"dfr fetch"
|
||||
"fetch"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -31,12 +31,33 @@ impl Command for LazyFetch {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
description: "Fetch a rows from the dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | fetch 2",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(2)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -68,13 +89,13 @@ impl Command for LazyFetch {
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazyFetch {})])
|
||||
// }
|
||||
//}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazyFetch {})])
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct LazyFillNA;
|
||||
|
||||
impl Command for LazyFillNA {
|
||||
fn name(&self) -> &str {
|
||||
"dfr fill-na"
|
||||
"fill-na"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -36,6 +36,14 @@ impl Command for LazyFillNA {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -44,22 +52,23 @@ impl Command for LazyFillNA {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let fill: Value = call.req(engine_state, stack, 0)?;
|
||||
let value = input.into_value(call.head);
|
||||
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?.into_polars();
|
||||
let expr = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.fill_nan(expr).into();
|
||||
if NuExpression::can_downcast(&value) {
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let fill = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let expr: NuExpression = expr.into_polars().fill_nan(fill).into();
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
let lazy = NuLazyFrame::try_from_value(value)?;
|
||||
let expr = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.into_polars().fill_nan(expr));
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazyFillNA {})])
|
||||
// }
|
||||
//}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct LazyFillNull;
|
||||
|
||||
impl Command for LazyFillNull {
|
||||
fn name(&self) -> &str {
|
||||
"dfr fill-null"
|
||||
"fill-null"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -30,12 +30,33 @@ impl Command for LazyFillNull {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
description: "Fills the null values by 0",
|
||||
example: "[1 2 2 3 3] | to-df | shift 2 | fill-null 0",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
vec![
|
||||
Value::test_int(0),
|
||||
Value::test_int(0),
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(2),
|
||||
],
|
||||
)])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -44,22 +65,35 @@ impl Command for LazyFillNull {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let fill: Value = call.req(engine_state, stack, 0)?;
|
||||
let value = input.into_value(call.head);
|
||||
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?.into_polars();
|
||||
let expr = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.fill_null(expr).into();
|
||||
if NuExpression::can_downcast(&value) {
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let fill = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let expr: NuExpression = expr.into_polars().fill_null(fill).into();
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
} else {
|
||||
let lazy = NuLazyFrame::try_from_value(value)?;
|
||||
let expr = NuExpression::try_from_value(fill)?.into_polars();
|
||||
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.into_polars().fill_null(expr));
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazyFillNull {})])
|
||||
// }
|
||||
//}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::series::Shift;
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazyFillNull {}), Box::new(Shift {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame, NuLazyGroupBy};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame, NuLazyGroupBy};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::Expr;
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ToLazyGroupBy;
|
||||
|
||||
impl Command for ToLazyGroupBy {
|
||||
fn name(&self) -> &str {
|
||||
"dfr group-by"
|
||||
"group-by"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -34,32 +34,81 @@ impl Command for ToLazyGroupBy {
|
||||
Example {
|
||||
description: "Group by and perform an aggregation",
|
||||
example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]]
|
||||
| dfr to-df
|
||||
| dfr group-by a
|
||||
| dfr aggregate [
|
||||
("b" | dfr min | dfr as "b_min")
|
||||
("b" | dfr max | dfr as "b_max")
|
||||
("b" | dfr sum | dfr as "b_sum")
|
||||
| to-df
|
||||
| group-by a
|
||||
| agg [
|
||||
(col b | min | as "b_min")
|
||||
(col b | max | as "b_max")
|
||||
(col b | sum | as "b_sum")
|
||||
]"#,
|
||||
result: None,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
),
|
||||
Column::new(
|
||||
"b_min".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b_max".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"b_sum".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(10)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Group by and perform an aggregation",
|
||||
example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]]
|
||||
| dfr to-df
|
||||
| dfr to-lazy
|
||||
| dfr group-by a
|
||||
| dfr aggregate [
|
||||
("b" | dfr min | dfr as "b_min")
|
||||
("b" | dfr max | dfr as "b_max")
|
||||
("b" | dfr sum | dfr as "b_sum")
|
||||
| to-lazy
|
||||
| group-by a
|
||||
| agg [
|
||||
(col b | min | as "b_min")
|
||||
(col b | max | as "b_max")
|
||||
(col b | sum | as "b_sum")
|
||||
]
|
||||
| dfr collect"#,
|
||||
result: None,
|
||||
| collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
),
|
||||
Column::new(
|
||||
"b_min".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4)],
|
||||
),
|
||||
Column::new(
|
||||
"b_max".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"b_sum".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(10)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -86,7 +135,8 @@ impl Command for ToLazyGroupBy {
|
||||
}
|
||||
|
||||
let value = input.into_value(call.head);
|
||||
let (lazy, from_eager) = NuLazyFrame::maybe_is_eager(value)?;
|
||||
let lazy = NuLazyFrame::try_from_value(value)?;
|
||||
let from_eager = lazy.from_eager;
|
||||
|
||||
let group_by = NuLazyGroupBy {
|
||||
group_by: Some(lazy.into_polars().groupby(&expressions)),
|
||||
@ -96,3 +146,23 @@ impl Command for ToLazyGroupBy {
|
||||
Ok(PipelineData::Value(group_by.into_value(call.head), None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
use crate::dataframe::expressions::{ExprAlias, ExprMax, ExprMin, ExprSum};
|
||||
use crate::dataframe::lazy::aggregate::LazyAggregate;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![
|
||||
Box::new(LazyAggregate {}),
|
||||
Box::new(ToLazyGroupBy {}),
|
||||
Box::new(ExprAlias {}),
|
||||
Box::new(ExprMin {}),
|
||||
Box::new(ExprMax {}),
|
||||
Box::new(ExprSum {}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::{Expr, JoinType};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct LazyJoin;
|
||||
|
||||
impl Command for LazyJoin {
|
||||
fn name(&self) -> &str {
|
||||
"dfr join"
|
||||
"join"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -45,21 +45,129 @@ impl Command for LazyJoin {
|
||||
vec![
|
||||
Example {
|
||||
description: "Join two lazy dataframes",
|
||||
example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr to-lazy);
|
||||
let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [1 "c" "var"] [1 "c" "const"]] | dfr to-lazy);
|
||||
$df_a | dfr join $df_b a foo | dfr collect"#,
|
||||
result: None,
|
||||
example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | to-lazy);
|
||||
let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | to-lazy);
|
||||
$df_a | join $df_b a foo | collect"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(1),
|
||||
Value::test_int(1),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![
|
||||
Value::test_string("a"),
|
||||
Value::test_string("b"),
|
||||
Value::test_string("c"),
|
||||
Value::test_string("c"),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"c".to_string(),
|
||||
vec![
|
||||
Value::test_int(0),
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"bar".to_string(),
|
||||
vec![
|
||||
Value::test_string("a"),
|
||||
Value::test_string("c"),
|
||||
Value::test_string("a"),
|
||||
Value::test_string("a"),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"ham".to_string(),
|
||||
vec![
|
||||
Value::test_string("let"),
|
||||
Value::test_string("var"),
|
||||
Value::test_string("let"),
|
||||
Value::test_string("let"),
|
||||
],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Join one eager dataframe with a lazy dataframe",
|
||||
example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr to-df);
|
||||
let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [1 "c" "var"] [1 "c" "const"]] | dfr to-lazy);
|
||||
$df_a | dfr join $df_b a foo"#,
|
||||
result: None,
|
||||
example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | to-df);
|
||||
let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | to-lazy);
|
||||
$df_a | join $df_b a foo"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(1),
|
||||
Value::test_int(1),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![
|
||||
Value::test_string("a"),
|
||||
Value::test_string("b"),
|
||||
Value::test_string("c"),
|
||||
Value::test_string("c"),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"c".to_string(),
|
||||
vec![
|
||||
Value::test_int(0),
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(3),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"bar".to_string(),
|
||||
vec![
|
||||
Value::test_string("a"),
|
||||
Value::test_string("c"),
|
||||
Value::test_string("a"),
|
||||
Value::test_string("a"),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"ham".to_string(),
|
||||
vec![
|
||||
Value::test_string("let"),
|
||||
Value::test_string("var"),
|
||||
Value::test_string("let"),
|
||||
Value::test_string("let"),
|
||||
],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -82,7 +190,7 @@ impl Command for LazyJoin {
|
||||
};
|
||||
|
||||
let other: Value = call.req(engine_state, stack, 0)?;
|
||||
let (other, _) = NuLazyFrame::maybe_is_eager(other)?;
|
||||
let other = NuLazyFrame::try_from_value(other)?;
|
||||
let other = other.into_polars();
|
||||
|
||||
let left_on: Value = call.req(engine_state, stack, 1)?;
|
||||
@ -114,10 +222,11 @@ impl Command for LazyJoin {
|
||||
let suffix = suffix.unwrap_or_else(|| "_x".into());
|
||||
|
||||
let value = input.into_value(call.head);
|
||||
let (lazy, from_eager) = NuLazyFrame::maybe_is_eager(value)?;
|
||||
let lazy = NuLazyFrame::try_from_value(value)?;
|
||||
let from_eager = lazy.from_eager;
|
||||
let lazy = lazy.into_polars();
|
||||
|
||||
let lazy: NuLazyFrame = lazy
|
||||
let lazy = lazy
|
||||
.join_builder()
|
||||
.with(other)
|
||||
.left_on(left_on)
|
||||
@ -125,15 +234,21 @@ impl Command for LazyJoin {
|
||||
.how(how)
|
||||
.force_parallel(true)
|
||||
.suffix(suffix)
|
||||
.finish()
|
||||
.into();
|
||||
.finish();
|
||||
|
||||
let res = if from_eager {
|
||||
lazy.collect(call.head)?.into_value(call.head)
|
||||
} else {
|
||||
lazy.into_value(call.head)
|
||||
};
|
||||
let lazy = NuLazyFrame::new(from_eager, lazy);
|
||||
|
||||
Ok(PipelineData::Value(res, None))
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazyJoin {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
/// Definition of multiple lazyframe commands using a macro rule
|
||||
/// All of these commands have an identical body and only require
|
||||
/// to have a change in the name, description and function
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuLazyFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
macro_rules! lazy_command {
|
||||
($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident) => {
|
||||
($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident, $test: ident) => {
|
||||
#[derive(Clone)]
|
||||
pub struct $command;
|
||||
|
||||
@ -30,6 +30,14 @@ macro_rules! lazy_command {
|
||||
$examples
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
@ -37,10 +45,21 @@ macro_rules! lazy_command {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.$func().into();
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?;
|
||||
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.into_polars().$func());
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod $test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new($command {})])
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -50,183 +69,195 @@ macro_rules! lazy_command {
|
||||
// Expands to a command definition for reverse
|
||||
lazy_command!(
|
||||
LazyReverse,
|
||||
"dfr reverse",
|
||||
"reverse",
|
||||
"Reverses the LazyFrame",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
reverse
|
||||
description: "Reverses the dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | reverse",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(4), Value::test_int(6),],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(2), Value::test_int(2), Value::test_int(2),],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
reverse,
|
||||
test_reverse
|
||||
);
|
||||
|
||||
// LazyCache command
|
||||
// Expands to a command definition for cache
|
||||
lazy_command!(
|
||||
LazyCache,
|
||||
"dfr cache",
|
||||
"cache",
|
||||
"Caches operations in a new LazyFrame",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
description: "Caches the result into a new LazyFrame",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | reverse | cache",
|
||||
result: None,
|
||||
}],
|
||||
cache
|
||||
cache,
|
||||
test_cache
|
||||
);
|
||||
|
||||
// Creates a command that may result in a lazy frame operation or
|
||||
// lazy frame expression
|
||||
macro_rules! lazy_expr_command {
|
||||
($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident) => {
|
||||
#[derive(Clone)]
|
||||
pub struct $command;
|
||||
|
||||
impl Command for $command {
|
||||
fn name(&self) -> &str {
|
||||
$name
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
$desc
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).category(Category::Custom("lazyframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
$examples
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value = input.into_value(call.head);
|
||||
|
||||
if NuExpression::can_downcast(&value) {
|
||||
let expr = NuExpression::try_from_value(value)?;
|
||||
let expr: NuExpression = expr.into_polars().$func().into();
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuExpression::into_value(expr, call.head),
|
||||
None,
|
||||
))
|
||||
} else if NuLazyFrame::can_downcast(&value) {
|
||||
let lazy = NuLazyFrame::try_from_value(value)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.$func().into();
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
} else {
|
||||
Err(ShellError::CantConvert(
|
||||
"expression or lazyframe".into(),
|
||||
value.get_type().to_string(),
|
||||
value.span()?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// LazyMax command
|
||||
// Expands to a command definition for max aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyMax,
|
||||
"dfr max",
|
||||
"Aggregates columns to their max value or creates a max expression",
|
||||
"max",
|
||||
"Aggregates columns to their max value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
max
|
||||
description: "Max value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | max",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(6)],),
|
||||
Column::new("b".to_string(), vec![Value::test_int(4)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
max,
|
||||
test_max
|
||||
);
|
||||
|
||||
// LazyMin command
|
||||
// Expands to a command definition for min aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyMin,
|
||||
"dfr min",
|
||||
"Aggregates columns to their min value or creates a min expression",
|
||||
"min",
|
||||
"Aggregates columns to their min value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
min
|
||||
description: "Min value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | min",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(1)],),
|
||||
Column::new("b".to_string(), vec![Value::test_int(1)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
min,
|
||||
test_min
|
||||
);
|
||||
|
||||
// LazySum command
|
||||
// Expands to a command definition for sum aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazySum,
|
||||
"dfr sum",
|
||||
"Aggregates columns to their sum value or creates a sum expression",
|
||||
"sum",
|
||||
"Aggregates columns to their sum value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
sum
|
||||
description: "Sums all columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | sum",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_int(11)],),
|
||||
Column::new("b".to_string(), vec![Value::test_int(7)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
sum,
|
||||
test_sum
|
||||
);
|
||||
|
||||
// LazyMean command
|
||||
// Expands to a command definition for mean aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyMean,
|
||||
"dfr mean",
|
||||
"Aggregates columns to their mean value or creates a mean expression",
|
||||
"mean",
|
||||
"Aggregates columns to their mean value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
mean
|
||||
description: "Mean value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | mean",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_float(4.0)],),
|
||||
Column::new("b".to_string(), vec![Value::test_float(2.0)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
mean,
|
||||
test_mean
|
||||
);
|
||||
|
||||
// LazyMedian command
|
||||
// Expands to a command definition for median aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyMedian,
|
||||
"dfr median",
|
||||
"Aggregates columns to their median value or creates a median expression",
|
||||
"median",
|
||||
"Aggregates columns to their median value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
median
|
||||
description: "Median value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | median",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_float(4.0)],),
|
||||
Column::new("b".to_string(), vec![Value::test_float(2.0)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
median,
|
||||
test_median
|
||||
);
|
||||
|
||||
// LazyStd command
|
||||
// Expands to a command definition for std aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyStd,
|
||||
"dfr std",
|
||||
"std",
|
||||
"Aggregates columns to their std value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
std
|
||||
description: "Std value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | std",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_float(2.0)],),
|
||||
Column::new("b".to_string(), vec![Value::test_float(0.0)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
std,
|
||||
test_std
|
||||
);
|
||||
|
||||
// LazyVar command
|
||||
// Expands to a command definition for var aggregation
|
||||
lazy_expr_command!(
|
||||
lazy_command!(
|
||||
LazyVar,
|
||||
"dfr var",
|
||||
"var",
|
||||
"Aggregates columns to their var value",
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}],
|
||||
var
|
||||
description: "Var value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | var",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_float(4.0)],),
|
||||
Column::new("b".to_string(), vec![Value::test_float(0.0)],),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},],
|
||||
var,
|
||||
test_var
|
||||
);
|
||||
|
@ -1,9 +1,9 @@
|
||||
mod aggregate;
|
||||
pub mod aggregate;
|
||||
mod collect;
|
||||
mod fetch;
|
||||
mod fill_na;
|
||||
mod fill_null;
|
||||
mod groupby;
|
||||
pub mod groupby;
|
||||
mod join;
|
||||
mod macro_commands;
|
||||
mod quantile;
|
||||
@ -13,10 +13,10 @@ mod to_lazy;
|
||||
|
||||
use nu_protocol::engine::StateWorkingSet;
|
||||
|
||||
use crate::dataframe::lazy::macro_commands::*;
|
||||
pub(crate) use crate::dataframe::lazy::macro_commands::*;
|
||||
|
||||
use crate::dataframe::lazy::aggregate::LazyAggregate;
|
||||
use crate::dataframe::lazy::collect::LazyCollect;
|
||||
pub use crate::dataframe::lazy::collect::LazyCollect;
|
||||
use crate::dataframe::lazy::fetch::LazyFetch;
|
||||
use crate::dataframe::lazy::fill_na::LazyFillNA;
|
||||
use crate::dataframe::lazy::fill_null::LazyFillNull;
|
||||
@ -25,7 +25,7 @@ use crate::dataframe::lazy::join::LazyJoin;
|
||||
use crate::dataframe::lazy::quantile::LazyQuantile;
|
||||
use crate::dataframe::lazy::select::LazySelect;
|
||||
use crate::dataframe::lazy::sort_by_expr::LazySortBy;
|
||||
use crate::dataframe::lazy::to_lazy::ToLazyFrame;
|
||||
pub use crate::dataframe::lazy::to_lazy::ToLazyFrame;
|
||||
|
||||
pub fn add_lazy_decls(working_set: &mut StateWorkingSet) {
|
||||
macro_rules! bind_command {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::dataframe::values::NuLazyFrame;
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuLazyFrame};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::QuantileInterpolOptions;
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct LazyQuantile;
|
||||
|
||||
impl Command for LazyQuantile {
|
||||
fn name(&self) -> &str {
|
||||
"dfr quantile"
|
||||
"quantile"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -31,12 +31,27 @@ impl Command for LazyQuantile {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
description: "quantile value from columns in a dataframe",
|
||||
example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | quantile 0.5",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new("a".to_string(), vec![Value::test_float(4.0)]),
|
||||
Column::new("b".to_string(), vec![Value::test_float(2.0)]),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -44,24 +59,27 @@ impl Command for LazyQuantile {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value = input.into_value(call.head);
|
||||
let quantile: f64 = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy
|
||||
.quantile(quantile, QuantileInterpolOptions::default())
|
||||
.into();
|
||||
let lazy = NuLazyFrame::try_from_value(value)?;
|
||||
let lazy = NuLazyFrame::new(
|
||||
lazy.from_eager,
|
||||
lazy.into_polars()
|
||||
.quantile(quantile, QuantileInterpolOptions::default()),
|
||||
);
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazyQuantile {})])
|
||||
// }
|
||||
//}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazyQuantile {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::dataframe::values::{NuExpression, NuLazyFrame};
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame};
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::Expr;
|
||||
|
||||
@ -13,7 +13,7 @@ pub struct LazySelect;
|
||||
|
||||
impl Command for LazySelect {
|
||||
fn name(&self) -> &str {
|
||||
"dfr select"
|
||||
"select"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -22,7 +22,7 @@ impl Command for LazySelect {
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
.rest(
|
||||
"select expressions",
|
||||
SyntaxShape::Any,
|
||||
"Expression(s) that define the column selection",
|
||||
@ -32,12 +32,27 @@ impl Command for LazySelect {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
description: "Select a column from the dataframe",
|
||||
example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | select a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(6), Value::test_int(4), Value::test_int(2)],
|
||||
)])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
@ -45,7 +60,11 @@ impl Command for LazySelect {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value: Value = call.req(engine_state, stack, 0)?;
|
||||
let vals: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let value = Value::List {
|
||||
vals,
|
||||
span: call.head,
|
||||
};
|
||||
let expressions = NuExpression::extract_exprs(value)?;
|
||||
|
||||
if expressions
|
||||
@ -59,20 +78,20 @@ impl Command for LazySelect {
|
||||
));
|
||||
}
|
||||
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?.into_polars();
|
||||
let lazy: NuLazyFrame = lazy.select(&expressions).into();
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?;
|
||||
let lazy = NuLazyFrame::new(lazy.from_eager, lazy.into_polars().select(&expressions));
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head)?, None))
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazySelect {})])
|
||||
// }
|
||||
//}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazySelect {})])
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use super::super::values::NuLazyFrame;
|
||||
use crate::dataframe::values::NuExpression;
|
||||
use crate::dataframe::values::{Column, NuDataFrame, NuExpression};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -12,7 +12,7 @@ pub struct LazySortBy;
|
||||
|
||||
impl Command for LazySortBy {
|
||||
fn name(&self) -> &str {
|
||||
"dfr sort-by"
|
||||
"sort-by"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -21,26 +21,77 @@ impl Command for LazySortBy {
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required(
|
||||
"filter expression",
|
||||
.rest(
|
||||
"sort expression",
|
||||
SyntaxShape::Any,
|
||||
"filtering expression",
|
||||
"sort expression for the dataframe",
|
||||
)
|
||||
.named(
|
||||
"reverse",
|
||||
SyntaxShape::List(Box::new(SyntaxShape::Boolean)),
|
||||
"list indicating if reverse search should be done in the column. Default is false",
|
||||
"Reverse sorting. Default is false",
|
||||
Some('r'),
|
||||
)
|
||||
.category(Category::Custom("lazyframe".into()))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "",
|
||||
example: "",
|
||||
result: None,
|
||||
}]
|
||||
vec![
|
||||
Example {
|
||||
description: "Sort dataframe by one column",
|
||||
example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | sort-by a",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![Value::test_int(1), Value::test_int(4), Value::test_int(6)],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![Value::test_int(4), Value::test_int(1), Value::test_int(2)],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
Example {
|
||||
description: "Sort column using two columns",
|
||||
example: "[[a b]; [6 2] [1 1] [1 4] [2 4]] | to-df | sort-by [a b] -r [false true]",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![
|
||||
Column::new(
|
||||
"a".to_string(),
|
||||
vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
Value::test_int(6),
|
||||
],
|
||||
),
|
||||
Column::new(
|
||||
"b".to_string(),
|
||||
vec![
|
||||
Value::test_int(4),
|
||||
Value::test_int(1),
|
||||
Value::test_int(4),
|
||||
Value::test_int(2),
|
||||
],
|
||||
),
|
||||
])
|
||||
.expect("simple df for test should not fail")
|
||||
.into_value(Span::test_data()),
|
||||
),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
@ -50,7 +101,11 @@ impl Command for LazySortBy {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let value: Value = call.req(engine_state, stack, 0)?;
|
||||
let vals: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||
let value = Value::List {
|
||||
vals,
|
||||
span: call.head,
|
||||
};
|
||||
let expressions = NuExpression::extract_exprs(value)?;
|
||||
|
||||
let reverse: Option<Vec<bool>> = call.get_flag(engine_state, stack, "reverse")?;
|
||||
@ -76,25 +131,25 @@ impl Command for LazySortBy {
|
||||
};
|
||||
|
||||
let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?;
|
||||
let lazy: NuLazyFrame = lazy
|
||||
.into_polars()
|
||||
.sort_by_exprs(&expressions, reverse)
|
||||
.into();
|
||||
let lazy = NuLazyFrame::new(
|
||||
lazy.from_eager,
|
||||
lazy.into_polars().sort_by_exprs(&expressions, reverse),
|
||||
);
|
||||
|
||||
Ok(PipelineData::Value(
|
||||
NuLazyFrame::into_value(lazy, call.head),
|
||||
NuLazyFrame::into_value(lazy, call.head)?,
|
||||
None,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
//#[cfg(test)]
|
||||
//mod test {
|
||||
// use super::super::super::test_dataframe::test_dataframe;
|
||||
// use super::*;
|
||||
//
|
||||
// #[test]
|
||||
// fn test_examples() {
|
||||
// test_dataframe(vec![Box::new(LazySortBy {})])
|
||||
// }
|
||||
//}
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::super::super::test_dataframe::test_dataframe;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
test_dataframe(vec![Box::new(LazySortBy {})])
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{NuDataFrame, NuLazyFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature,
|
||||
Category, Example, PipelineData, ShellError, Signature, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct ToLazyFrame;
|
||||
|
||||
impl Command for ToLazyFrame {
|
||||
fn name(&self) -> &str {
|
||||
"dfr to-lazy"
|
||||
"to-lazy"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -25,11 +25,19 @@ impl Command for ToLazyFrame {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Takes a dictionary and creates a lazy dataframe",
|
||||
example: "[[a b];[1 2] [3 4]] | dfr to-df | dfl to-lazy",
|
||||
example: "[[a b];[1 2] [3 4]] | to-lazy",
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Any
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
@ -39,7 +47,11 @@ impl Command for ToLazyFrame {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let df = NuDataFrame::try_from_iter(input.into_iter())?;
|
||||
let lazy = NuLazyFrame::from_dataframe(df);
|
||||
let value = Value::CustomValue {
|
||||
val: Box::new(lazy),
|
||||
span: call.head,
|
||||
};
|
||||
|
||||
Ok(PipelineData::Value(lazy.into_value(call.head), None))
|
||||
Ok(PipelineData::Value(value, None))
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct AllFalse;
|
||||
|
||||
impl Command for AllFalse {
|
||||
fn name(&self) -> &str {
|
||||
"dfr all-false"
|
||||
"all-false"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for AllFalse {
|
||||
vec![
|
||||
Example {
|
||||
description: "Returns true if all values are false",
|
||||
example: "[false false false] | dfr to-df | dfr all-false",
|
||||
example: "[false false false] | to-df | all-false",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"all_false".to_string(),
|
||||
@ -38,9 +38,9 @@ impl Command for AllFalse {
|
||||
},
|
||||
Example {
|
||||
description: "Checks the result from a comparison",
|
||||
example: r#"let s = ([5 6 2 10] | dfr to-df);
|
||||
example: r#"let s = ([5 6 2 10] | to-df);
|
||||
let res = ($s > 9);
|
||||
$res | dfr all-false"#,
|
||||
$res | all-false"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"all_false".to_string(),
|
||||
@ -53,6 +53,14 @@ impl Command for AllFalse {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -11,7 +11,7 @@ pub struct AllTrue;
|
||||
|
||||
impl Command for AllTrue {
|
||||
fn name(&self) -> &str {
|
||||
"dfr all-true"
|
||||
"all-true"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for AllTrue {
|
||||
vec![
|
||||
Example {
|
||||
description: "Returns true if all values are true",
|
||||
example: "[true true true] | dfr to-df | dfr all-true",
|
||||
example: "[true true true] | to-df | all-true",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"all_true".to_string(),
|
||||
@ -38,9 +38,9 @@ impl Command for AllTrue {
|
||||
},
|
||||
Example {
|
||||
description: "Checks the result from a comparison",
|
||||
example: r#"let s = ([5 6 2 8] | dfr to-df);
|
||||
example: r#"let s = ([5 6 2 8] | to-df);
|
||||
let res = ($s > 9);
|
||||
$res | dfr all-true"#,
|
||||
$res | all-true"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"all_true".to_string(),
|
||||
@ -53,6 +53,14 @@ impl Command for AllTrue {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{IntoSeries, NewChunkedArray, UInt32Chunked};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ArgMax;
|
||||
|
||||
impl Command for ArgMax {
|
||||
fn name(&self) -> &str {
|
||||
"dfr arg-max"
|
||||
"arg-max"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for ArgMax {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Returns index for max value",
|
||||
example: "[1 3 2] | dfr to-df | dfr arg-max",
|
||||
example: "[1 3 2] | to-df | arg-max",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"arg_max".to_string(),
|
||||
@ -38,6 +38,14 @@ impl Command for ArgMax {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{IntoSeries, NewChunkedArray, UInt32Chunked};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ArgMin;
|
||||
|
||||
impl Command for ArgMin {
|
||||
fn name(&self) -> &str {
|
||||
"dfr arg-min"
|
||||
"arg-min"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for ArgMin {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Returns index for min value",
|
||||
example: "[1 3 2] | dfr to-df | dfr arg-min",
|
||||
example: "[1 3 2] | to-df | arg-min",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"arg_min".to_string(),
|
||||
@ -38,6 +38,14 @@ impl Command for ArgMin {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -4,7 +4,8 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type,
|
||||
Value,
|
||||
};
|
||||
use polars::prelude::{DataType, IntoSeries};
|
||||
|
||||
@ -44,7 +45,7 @@ pub struct Cumulative;
|
||||
|
||||
impl Command for Cumulative {
|
||||
fn name(&self) -> &str {
|
||||
"dfr cumulative"
|
||||
"cumulative"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -61,7 +62,7 @@ impl Command for Cumulative {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Cumulative sum for a series",
|
||||
example: "[1 2 3 4 5] | dfr to-df | dfr cumulative sum",
|
||||
example: "[1 2 3 4 5] | to-df | cumulative sum",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0_cumulative_sum".to_string(),
|
||||
@ -79,6 +80,14 @@ impl Command for Cumulative {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -4,7 +4,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape,
|
||||
Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type,
|
||||
};
|
||||
use polars::prelude::{IntoSeries, Utf8Methods};
|
||||
|
||||
@ -13,7 +13,7 @@ pub struct AsDate;
|
||||
|
||||
impl Command for AsDate {
|
||||
fn name(&self) -> &str {
|
||||
"dfr as-date"
|
||||
"as-date"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -37,11 +37,19 @@ impl Command for AsDate {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Converts string to date",
|
||||
example: r#"["2021-12-30" "2021-12-31"] | dfr to-df | dfr as-datetime "%Y-%m-%d""#,
|
||||
example: r#"["2021-12-30" "2021-12-31"] | to-df | as-datetime "%Y-%m-%d""#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -5,7 +5,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
|
||||
};
|
||||
use polars::prelude::{IntoSeries, TimeUnit, Utf8Methods};
|
||||
|
||||
@ -14,7 +14,7 @@ pub struct AsDateTime;
|
||||
|
||||
impl Command for AsDateTime {
|
||||
fn name(&self) -> &str {
|
||||
"dfr as-datetime"
|
||||
"as-datetime"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -46,7 +46,7 @@ impl Command for AsDateTime {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Converts string to datetime",
|
||||
example: r#"["2021-12-30 00:00:00" "2021-12-31 00:00:00"] | dfr to-df | dfr as-datetime "%Y-%m-%d %H:%M:%S""#,
|
||||
example: r#"["2021-12-30 00:00:00" "2021-12-31 00:00:00"] | to-df | as-datetime "%Y-%m-%d %H:%M:%S""#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"datetime".to_string(),
|
||||
@ -75,6 +75,14 @@ impl Command for AsDateTime {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetDay;
|
||||
|
||||
impl Command for GetDay {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-day"
|
||||
"get-day"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetDay {
|
||||
vec![Example {
|
||||
description: "Returns day from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-day"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-day"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetDay {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetHour;
|
||||
|
||||
impl Command for GetHour {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-hour"
|
||||
"get-hour"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetHour {
|
||||
vec![Example {
|
||||
description: "Returns hour from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-hour"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-hour"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetHour {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetMinute;
|
||||
|
||||
impl Command for GetMinute {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-minute"
|
||||
"get-minute"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetMinute {
|
||||
vec![Example {
|
||||
description: "Returns minute from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-minute"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-minute"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetMinute {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetMonth;
|
||||
|
||||
impl Command for GetMonth {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-month"
|
||||
"get-month"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetMonth {
|
||||
vec![Example {
|
||||
description: "Returns month from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-month"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-month"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetMonth {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetNanosecond;
|
||||
|
||||
impl Command for GetNanosecond {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-nanosecond"
|
||||
"get-nanosecond"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetNanosecond {
|
||||
vec![Example {
|
||||
description: "Returns nanosecond from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-nanosecond"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-nanosecond"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetNanosecond {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetOrdinal;
|
||||
|
||||
impl Command for GetOrdinal {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-ordinal"
|
||||
"get-ordinal"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetOrdinal {
|
||||
vec![Example {
|
||||
description: "Returns ordinal from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-ordinal"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-ordinal"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetOrdinal {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetSecond;
|
||||
|
||||
impl Command for GetSecond {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-second"
|
||||
"get-second"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetSecond {
|
||||
vec![Example {
|
||||
description: "Returns second from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-second"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-second"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetSecond {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetWeek;
|
||||
|
||||
impl Command for GetWeek {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-week"
|
||||
"get-week"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetWeek {
|
||||
vec![Example {
|
||||
description: "Returns week from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-week"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-week"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetWeek {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetWeekDay;
|
||||
|
||||
impl Command for GetWeekDay {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-weekday"
|
||||
"get-weekday"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetWeekDay {
|
||||
vec![Example {
|
||||
description: "Returns weekday from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-weekday"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-weekday"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetWeekDay {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{DatetimeMethods, IntoSeries};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct GetYear;
|
||||
|
||||
impl Command for GetYear {
|
||||
fn name(&self) -> &str {
|
||||
"dfr get-year"
|
||||
"get-year"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -27,8 +27,8 @@ impl Command for GetYear {
|
||||
vec![Example {
|
||||
description: "Returns year from a date",
|
||||
example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC');
|
||||
let df = ([$dt $dt] | dfr to-df);
|
||||
$df | dfr get-year"#,
|
||||
let df = ([$dt $dt] | to-df);
|
||||
$df | get-year"#,
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"0".to_string(),
|
||||
@ -40,6 +40,14 @@ impl Command for GetYear {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::{IntoSeries, SortOptions};
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ArgSort;
|
||||
|
||||
impl Command for ArgSort {
|
||||
fn name(&self) -> &str {
|
||||
"dfr arg-sort"
|
||||
"arg-sort"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -30,7 +30,7 @@ impl Command for ArgSort {
|
||||
vec![
|
||||
Example {
|
||||
description: "Returns indexes for a sorted series",
|
||||
example: "[1 2 2 3 3] | dfr to-df | dfr arg-sort",
|
||||
example: "[1 2 2 3 3] | to-df | arg-sort",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"arg_sort".to_string(),
|
||||
@ -48,7 +48,7 @@ impl Command for ArgSort {
|
||||
},
|
||||
Example {
|
||||
description: "Returns indexes for a sorted series",
|
||||
example: "[1 2 2 3 3] | dfr to-df | dfr arg-sort -r",
|
||||
example: "[1 2 2 3 3] | to-df | arg-sort -r",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"arg_sort".to_string(),
|
||||
@ -67,6 +67,14 @@ impl Command for ArgSort {
|
||||
]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
|
||||
};
|
||||
use polars::prelude::IntoSeries;
|
||||
|
||||
@ -12,7 +12,7 @@ pub struct ArgTrue;
|
||||
|
||||
impl Command for ArgTrue {
|
||||
fn name(&self) -> &str {
|
||||
"dfr arg-true"
|
||||
"arg-true"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -26,7 +26,7 @@ impl Command for ArgTrue {
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Returns indexes where values are true",
|
||||
example: "[false true false] | dfr to-df | dfr arg-true",
|
||||
example: "[false true false] | to-df | arg-true",
|
||||
result: Some(
|
||||
NuDataFrame::try_from_columns(vec![Column::new(
|
||||
"arg_true".to_string(),
|
||||
@ -38,6 +38,14 @@ impl Command for ArgTrue {
|
||||
}]
|
||||
}
|
||||
|
||||
fn input_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn output_type(&self) -> Type {
|
||||
Type::Custom("dataframe".into())
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user