forked from extern/nushell
Restructuring
This commit is contained in:
parent
73deeb69db
commit
fc173c46d8
171
Cargo.lock
generated
171
Cargo.lock
generated
@ -9,7 +9,7 @@ dependencies = [
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -77,6 +77,16 @@ dependencies = [
|
||||
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.11"
|
||||
@ -570,7 +580,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -609,7 +619,7 @@ dependencies = [
|
||||
"ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -622,7 +632,7 @@ dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -632,7 +642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -642,7 +652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -661,7 +671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -673,7 +683,7 @@ dependencies = [
|
||||
"derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -684,7 +694,7 @@ dependencies = [
|
||||
"darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -697,7 +707,7 @@ dependencies = [
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -844,7 +854,7 @@ dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive_internals 0.24.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -898,7 +908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -961,16 +971,37 @@ version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
name = "futures-async-stream"
|
||||
version = "0.1.0-alpha.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-async-stream-macro 0.1.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-async-stream-macro"
|
||||
version = "0.1.0-alpha.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel-preview"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@ -984,56 +1015,51 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-channel-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-channel-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-executor-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-channel-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-util-preview"
|
||||
version = "0.3.0-alpha.16"
|
||||
version = "0.3.0-alpha.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1042,11 +1068,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures_codec"
|
||||
version = "0.2.2"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1065,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1445,7 +1471,7 @@ dependencies = [
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -1648,6 +1674,7 @@ dependencies = [
|
||||
"adhoc_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ansi_term 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"async-trait 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byte-unit 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1664,9 +1691,10 @@ dependencies = [
|
||||
"dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"enum-utils 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"enum_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures_codec 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-async-stream 0.1.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures_codec 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getset 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"git2 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1697,7 +1725,6 @@ dependencies = [
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde-hjson 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_bytes 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_ini 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -1721,7 +1748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2000,6 +2027,16 @@ dependencies = [
|
||||
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0-alpha.4"
|
||||
@ -2636,7 +2673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2645,7 +2682,7 @@ version = "0.24.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2781,7 +2818,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.37"
|
||||
version = "0.15.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -2796,7 +2833,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -3115,7 +3152,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3287,7 +3324,7 @@ dependencies = [
|
||||
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -3307,7 +3344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-backend 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasm-bindgen-shared 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@ -3431,6 +3468,7 @@ dependencies = [
|
||||
"checksum app_dirs 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e73a24bad9bd6a94d6395382a6c69fe071708ae4409f763c5475e14ee896313d"
|
||||
"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
|
||||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||
"checksum async-trait 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "41f6b40ac5df0ab7ef35112d7a593428ca62bcaabcc7de20f88b506cf798928d"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
|
||||
"checksum backtrace 0.3.30 (registry+https://github.com/rust-lang/crates.io-index)" = "ada4c783bb7e7443c14e0480f429ae2cc99da95065aeab7ee1b81ada0419404f"
|
||||
@ -3532,15 +3570,17 @@ dependencies = [
|
||||
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
"checksum futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "a2037ec1c6c1c4f79557762eab1f7eae1f64f6cb418ace90fae88f0942b60139"
|
||||
"checksum futures-channel-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4cd523712fc272e9b714669165a2832debee5a5b7e409bfccdc7c0d5cd0cf07a"
|
||||
"checksum futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "719770f328642b657b849856bb5a607db9538dd5bb3000122e5ead55d0a58c36"
|
||||
"checksum futures-async-stream 0.1.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4aecac975d38ff13b935de313e12fded407231b0d563e7493fac40463272a2f"
|
||||
"checksum futures-async-stream-macro 0.1.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bbd6c677284a4bb3c043193ad20017f06c61cca34327ce5b0682691f92a182e"
|
||||
"checksum futures-channel-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "21c71ed547606de08e9ae744bb3c6d80f5627527ef31ecf2a7210d0e67bc8fae"
|
||||
"checksum futures-core-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4b141ccf9b7601ef987f36f1c0d9522f76df3bba1cf2e63bfacccc044c4558f5"
|
||||
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
|
||||
"checksum futures-executor-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "315dc58c908535d059576a329b86cd185933433382cfcd394fb2fa353330de03"
|
||||
"checksum futures-io-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cca0bf7a1f39c9d32b797b0def93d5932aa71796236aad6b549bac6f7df159a3"
|
||||
"checksum futures-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfeac5f016a4b5835bb93eb7961f50a64f0e001207562703d9ddf4109d7b263"
|
||||
"checksum futures-sink-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "49dcfdacd6b5974ca0b9b78bc38ffd1071da0206179735c3df82e279f5b784e4"
|
||||
"checksum futures-util-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f7a0451b9c5047c2b9ab93425ffd0793165511e93c04b977cd45fbd41c6e34b2"
|
||||
"checksum futures_codec 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b60f48aa03e365df015d2fbf0b79f17b440350c268a5e20305da17b394adcc1e"
|
||||
"checksum futures-executor-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "87ba260fe51080ba37f063ad5b0732c4ff1f737ea18dcb67833d282cdc2c6f14"
|
||||
"checksum futures-io-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "082e402605fcb8b1ae1e5ba7d7fdfd3e31ef510e2a8367dd92927bb41ae41b3a"
|
||||
"checksum futures-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "bf25f91c8a9a1f64c451e91b43ba269ed359b9f52d35ed4b3ce3f9c842435867"
|
||||
"checksum futures-sink-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4309a25a1069a1f3c10647b227b9afe6722b67a030d3f00a9cbdc171fc038de4"
|
||||
"checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e"
|
||||
"checksum futures_codec 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "36552cd31353fd135114510d53b8d120758120c36aa636a9341970f9efb1e4a0"
|
||||
"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55"
|
||||
"checksum getset 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "19fbde0fad0c1c1f9474694b1f5c9ba22b09f2f74f74e6d2bd19c43f6656e2cb"
|
||||
"checksum gif 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "86c2f2b597d6e05c86ee5947b2223bda468fe8dad3e88e2a6520869322aaf568"
|
||||
@ -3634,6 +3674,7 @@ dependencies = [
|
||||
"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e"
|
||||
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
"checksum pin-project 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2714268752963de91be73ea2689c3c63d2389b14fad04d033923e20cb3a1d99a"
|
||||
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
|
||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||
"checksum plist 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a9f075f6394100e7c105ed1af73fb1859d6fd14e49d4290d578120beb167f"
|
||||
@ -3723,7 +3764,7 @@ dependencies = [
|
||||
"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum subprocess 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "28fc0f40f0c0da73339d347aa7d6d2b90341a95683a47722bc4eebed71ff3c00"
|
||||
"checksum syn 0.15.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e11410033fd5cf69a1cf2084604e011190c56f11e08ffc53df880f5f65f1c6e4"
|
||||
"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e"
|
||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
||||
"checksum syntect 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e80b8831c5a543192ffc3727f01cf0e57579c6ac15558e3048bfb5708892167b"
|
||||
"checksum sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "76d6cf7b349b6a6daaf7a3797227e2f4108c8dd398e0aca7e29b9fb239948541"
|
||||
|
11
Cargo.toml
11
Cargo.toml
@ -28,18 +28,19 @@ chrono-humanize = "0.0.11"
|
||||
byte-unit = "2.1.0"
|
||||
ordered-float = {version = "1.0.2", features = ["serde"]}
|
||||
prettyprint = "0.7.0"
|
||||
futures-preview = { version = "=0.3.0-alpha.16", features = ["compat", "io-compat"] }
|
||||
futures-sink-preview = "=0.3.0-alpha.16"
|
||||
futures_codec = "0.2.2"
|
||||
futures-preview = { version = "=0.3.0-alpha.17", features = ["compat", "io-compat"] }
|
||||
futures-sink-preview = "=0.3.0-alpha.17"
|
||||
futures-async-stream = "0.1.0-alpha.1"
|
||||
async-trait = ""
|
||||
futures_codec = "0.2.5"
|
||||
term = "0.5.2"
|
||||
bytes = "0.4.12"
|
||||
log = "0.4.7"
|
||||
pretty_env_logger = "0.3.0"
|
||||
serde = "1.0.94"
|
||||
serde = { version = "1.0.94", features = ["derive"] }
|
||||
serde_json = "1.0.40"
|
||||
serde-hjson = "0.9.0"
|
||||
serde_yaml = "0.8"
|
||||
serde_derive = "1.0.94"
|
||||
serde_bytes = "0.11.1"
|
||||
getset = "0.0.7"
|
||||
logos = "0.10.0-rc2"
|
||||
|
96
src/cli.rs
96
src/cli.rs
@ -1,18 +1,17 @@
|
||||
use crate::commands::autoview;
|
||||
use crate::commands::classified::SinkCommand;
|
||||
use crate::commands::classified::{
|
||||
ClassifiedCommand, ClassifiedInputStream, ClassifiedPipeline, ExternalCommand, InternalCommand,
|
||||
StreamNext,
|
||||
};
|
||||
use crate::commands::command::sink;
|
||||
use crate::commands::plugin::JsonRpc;
|
||||
use crate::commands::plugin::{PluginCommand, PluginSink};
|
||||
use crate::commands::plugin::PluginCommand;
|
||||
use crate::commands::{static_command, Command};
|
||||
use crate::context::Context;
|
||||
crate use crate::errors::ShellError;
|
||||
use crate::git::current_branch;
|
||||
use crate::object::Value;
|
||||
use crate::parser::parse::span::Spanned;
|
||||
use crate::parser::registry::CommandConfig;
|
||||
use crate::parser::registry::Signature;
|
||||
use crate::parser::{hir, Pipeline, PipelineElement, TokenNode};
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -61,8 +60,7 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel
|
||||
let mut input = String::new();
|
||||
match reader.read_line(&mut input) {
|
||||
Ok(_) => {
|
||||
let response =
|
||||
serde_json::from_str::<JsonRpc<Result<CommandConfig, ShellError>>>(&input);
|
||||
let response = serde_json::from_str::<JsonRpc<Result<Signature, ShellError>>>(&input);
|
||||
match response {
|
||||
Ok(jrpc) => match jrpc.params {
|
||||
Ok(params) => {
|
||||
@ -70,15 +68,10 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel
|
||||
if params.is_filter {
|
||||
let fname = fname.to_string();
|
||||
let name = params.name.clone();
|
||||
context.add_commands(vec![Arc::new(PluginCommand::new(
|
||||
context.add_commands(vec![static_command(PluginCommand::new(
|
||||
name, fname, params,
|
||||
))]);
|
||||
Ok(())
|
||||
} else if params.is_sink {
|
||||
let fname = fname.to_string();
|
||||
let name = params.name.clone();
|
||||
context.add_sinks(vec![Arc::new(PluginSink::new(name, fname, params))]);
|
||||
Ok(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@ -158,10 +151,8 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
command("ps", Box::new(ps::ps)),
|
||||
command("ls", Box::new(ls::ls)),
|
||||
command("sysinfo", Box::new(sysinfo::sysinfo)),
|
||||
command("cd", Box::new(cd::cd)),
|
||||
command("size", Box::new(size::size)),
|
||||
command("from-yaml", Box::new(from_yaml::from_yaml)),
|
||||
command("get", Box::new(get::get)),
|
||||
command("exit", Box::new(exit::exit)),
|
||||
command("lines", Box::new(lines::lines)),
|
||||
command("split-column", Box::new(split_column::split_column)),
|
||||
@ -175,19 +166,18 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
||||
command("to-toml", Box::new(to_toml::to_toml)),
|
||||
command("to-yaml", Box::new(to_yaml::to_yaml)),
|
||||
command("sort-by", Box::new(sort_by::sort_by)),
|
||||
Arc::new(Remove),
|
||||
Arc::new(Open),
|
||||
Arc::new(Where),
|
||||
Arc::new(Config),
|
||||
Arc::new(SkipWhile),
|
||||
]);
|
||||
|
||||
context.add_sinks(vec![
|
||||
sink("autoview", Box::new(autoview::autoview)),
|
||||
sink("clip", Box::new(clip::clip)),
|
||||
sink("save", Box::new(save::save)),
|
||||
sink("table", Box::new(table::table)),
|
||||
sink("vtable", Box::new(vtable::vtable)),
|
||||
static_command(Get),
|
||||
static_command(Cd),
|
||||
static_command(Remove),
|
||||
static_command(Open),
|
||||
static_command(Where),
|
||||
static_command(Config),
|
||||
static_command(SkipWhile),
|
||||
static_command(Clip),
|
||||
static_command(Autoview),
|
||||
// command("save", Box::new(save::save)),
|
||||
// command("table", Box::new(table::table)),
|
||||
// command("vtable", Box::new(vtable::vtable)),
|
||||
]);
|
||||
}
|
||||
let _ = load_plugins(&mut context);
|
||||
@ -341,17 +331,19 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
|
||||
.map_err(|err| (line.clone(), err))?;
|
||||
|
||||
match pipeline.commands.last() {
|
||||
Some(ClassifiedCommand::Sink(_)) => {}
|
||||
Some(ClassifiedCommand::External(_)) => {}
|
||||
_ => pipeline.commands.push(ClassifiedCommand::Sink(SinkCommand {
|
||||
command: sink("autoview", Box::new(autoview::autoview)),
|
||||
name_span: None,
|
||||
args: hir::Call::new(
|
||||
Box::new(hir::Expression::synthetic_string("autoview")),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
})),
|
||||
_ => pipeline
|
||||
.commands
|
||||
.push(ClassifiedCommand::Internal(InternalCommand {
|
||||
command: static_command(autoview::Autoview),
|
||||
name_span: None,
|
||||
source_map: ctx.source_map,
|
||||
args: hir::Call::new(
|
||||
Box::new(hir::Expression::synthetic_string("autoview")),
|
||||
None,
|
||||
None,
|
||||
),
|
||||
})),
|
||||
}
|
||||
|
||||
let mut input = ClassifiedInputStream::new();
|
||||
@ -379,18 +371,6 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
|
||||
)
|
||||
}
|
||||
|
||||
(Some(ClassifiedCommand::Sink(SinkCommand { name_span, .. })), Some(_)) => {
|
||||
return LineResult::Error(line.clone(), ShellError::maybe_labeled_error("Commands like table, save, and autoview must come last in the pipeline", "must come last", name_span));
|
||||
}
|
||||
|
||||
(Some(ClassifiedCommand::Sink(left)), None) => {
|
||||
let input_vec: Vec<Spanned<Value>> = input.objects.into_vec().await;
|
||||
if let Err(err) = left.run(ctx, input_vec, &Text::from(line)) {
|
||||
return LineResult::Error(line.clone(), err);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
(
|
||||
Some(ClassifiedCommand::Internal(left)),
|
||||
Some(ClassifiedCommand::External(_)),
|
||||
@ -485,7 +465,7 @@ fn classify_command(
|
||||
match context.has_command(name) {
|
||||
true => {
|
||||
let command = context.get_command(name);
|
||||
let config = command.config();
|
||||
let config = command.signature();
|
||||
|
||||
trace!(target: "nu::build_pipeline", "classifying {:?}", config);
|
||||
|
||||
@ -498,20 +478,8 @@ fn classify_command(
|
||||
args,
|
||||
}))
|
||||
}
|
||||
false => match context.has_sink(name) {
|
||||
true => {
|
||||
let command = context.get_sink(name);
|
||||
let config = command.config();
|
||||
|
||||
let args = config.parse_args(call, context.registry(), source)?;
|
||||
|
||||
Ok(ClassifiedCommand::Sink(SinkCommand {
|
||||
command,
|
||||
name_span: Some(head.span().clone()),
|
||||
args,
|
||||
}))
|
||||
}
|
||||
false => {
|
||||
false => match context.get_command(name).as_ref() {
|
||||
Command::Static(command) => {
|
||||
let arg_list_strings: Vec<Spanned<String>> = match call.children() {
|
||||
//Some(args) => args.iter().map(|i| i.as_external_arg(source)).collect(),
|
||||
Some(args) => args
|
||||
|
@ -42,8 +42,15 @@ crate mod trim;
|
||||
crate mod vtable;
|
||||
crate mod where_;
|
||||
|
||||
crate use command::{command, EvaluatedStaticCommandArgs};
|
||||
crate use autoview::Autoview;
|
||||
crate use cd::Cd;
|
||||
crate use clip::Clip;
|
||||
crate use command::{
|
||||
command, static_command, CallInfo, Command, CommandArgs, EvaluatedStaticCommandArgs,
|
||||
StaticCommand, UnevaluatedCallInfo,
|
||||
};
|
||||
crate use config::Config;
|
||||
crate use get::Get;
|
||||
crate use open::Open;
|
||||
crate use rm::Remove;
|
||||
crate use skip_while::SkipWhile;
|
||||
|
@ -1,11 +1,31 @@
|
||||
use crate::commands::command::SinkCommandArgs;
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::context::{SourceMap, SpanSource};
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::GenericView;
|
||||
use crate::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
pub struct Autoview;
|
||||
|
||||
impl StaticCommand for Autoview {
|
||||
fn name(&self) -> &str {
|
||||
"autoview"
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, autoview)?.run()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("autoview").sink()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn autoview(args: (), context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
if let Spanned {
|
||||
item: Value::Binary(_),
|
||||
@ -27,7 +47,7 @@ pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(OutputStream::empty())
|
||||
}
|
||||
|
||||
fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {
|
||||
|
@ -1,27 +1,54 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::prelude::*;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||
let env = args.env.clone();
|
||||
let env = env.lock().unwrap();
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let cwd = env.path().to_path_buf();
|
||||
pub struct Cd;
|
||||
|
||||
let path = match args.nth(0) {
|
||||
#[derive(Deserialize)]
|
||||
pub struct CdArgs {
|
||||
target: Option<Spanned<PathBuf>>,
|
||||
}
|
||||
|
||||
impl StaticCommand for Cd {
|
||||
fn name(&self) -> &str {
|
||||
"cd"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("cd")
|
||||
.optional("target", SyntaxType::Path)
|
||||
.filter()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, cd)?.run()
|
||||
// cd(args, registry)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cd(CdArgs { target }: CdArgs, context: RunnableContext) -> Result<OutputStream, ShellError> {
|
||||
let cwd = context.cwd().to_path_buf();
|
||||
|
||||
let path = match &target {
|
||||
None => match dirs::home_dir() {
|
||||
Some(o) => o,
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Can not change to home directory",
|
||||
"can not go to home",
|
||||
args.name_span(),
|
||||
context.name,
|
||||
))
|
||||
}
|
||||
},
|
||||
Some(v) => {
|
||||
let target = v.as_string()?;
|
||||
match dunce::canonicalize(cwd.join(target).as_path()) {
|
||||
// let target = v.item.as_string()?;
|
||||
match dunce::canonicalize(cwd.join(&v.item()).as_path()) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return Err(ShellError::labeled_error(
|
||||
@ -38,11 +65,11 @@ pub fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
|
||||
match env::set_current_dir(&path) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
if args.len() > 0 {
|
||||
if let Some(path) = target {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to directory",
|
||||
"directory not found",
|
||||
args.nth(0).unwrap().span.clone(),
|
||||
path.span,
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::string("Can not change to directory"));
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::commands::command::Sink;
|
||||
use crate::commands::Command;
|
||||
use crate::context::SourceMap;
|
||||
use crate::evaluate::Scope;
|
||||
use crate::parser::{hir, Span, Spanned, TokenNode};
|
||||
use crate::prelude::*;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
@ -83,7 +82,6 @@ crate enum ClassifiedCommand {
|
||||
#[allow(unused)]
|
||||
Expr(TokenNode),
|
||||
Internal(InternalCommand),
|
||||
Sink(SinkCommand),
|
||||
External(ExternalCommand),
|
||||
}
|
||||
|
||||
@ -93,34 +91,13 @@ impl ClassifiedCommand {
|
||||
match self {
|
||||
ClassifiedCommand::Expr(token) => token.span(),
|
||||
ClassifiedCommand::Internal(internal) => internal.name_span.into(),
|
||||
ClassifiedCommand::Sink(sink) => sink.name_span.into(),
|
||||
ClassifiedCommand::External(external) => external.name_span.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
crate struct SinkCommand {
|
||||
crate command: Arc<dyn Sink>,
|
||||
crate name_span: Option<Span>,
|
||||
crate args: hir::Call,
|
||||
}
|
||||
|
||||
impl SinkCommand {
|
||||
crate fn run(
|
||||
self,
|
||||
context: &mut Context,
|
||||
input: Vec<Spanned<Value>>,
|
||||
source: &Text,
|
||||
) -> Result<(), ShellError> {
|
||||
let args = self
|
||||
.args
|
||||
.evaluate(context.registry(), &Scope::empty(), source)?;
|
||||
context.run_sink(self.command, self.name_span.clone(), args, input)
|
||||
}
|
||||
}
|
||||
|
||||
crate struct InternalCommand {
|
||||
crate command: Arc<dyn Command>,
|
||||
crate command: Arc<Command>,
|
||||
crate name_span: Option<Span>,
|
||||
crate source_map: SourceMap,
|
||||
crate args: hir::Call,
|
||||
@ -142,14 +119,16 @@ impl InternalCommand {
|
||||
let objects: InputStream =
|
||||
trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects);
|
||||
|
||||
let result = context.run_command(
|
||||
self.command,
|
||||
self.name_span.clone(),
|
||||
self.source_map,
|
||||
self.args,
|
||||
source,
|
||||
objects,
|
||||
)?;
|
||||
let result = context
|
||||
.run_command(
|
||||
self.command,
|
||||
self.name_span.clone(),
|
||||
self.source_map,
|
||||
self.args,
|
||||
source,
|
||||
objects,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let mut result = result.values;
|
||||
|
||||
|
@ -1,25 +1,71 @@
|
||||
use crate::commands::command::SinkCommandArgs;
|
||||
use crate::commands::{CommandArgs, StaticCommand};
|
||||
use crate::context::CommandRegistry;
|
||||
use crate::errors::{labelled, ShellError};
|
||||
use crate::prelude::*;
|
||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||
use futures::stream::StreamExt;
|
||||
use futures_async_stream::async_stream_block;
|
||||
|
||||
pub fn clip(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
pub struct Clip;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ClipArgs {}
|
||||
|
||||
impl StaticCommand for Clip {
|
||||
fn name(&self) -> &str {
|
||||
"clip"
|
||||
}
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, clip)?.run()
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("clip").sink()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clip(
|
||||
ClipArgs {}: ClipArgs,
|
||||
RunnableContext { input, name, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let stream = async_stream_block! {
|
||||
let values: Vec<Spanned<Value>> = input.values.collect().await;
|
||||
|
||||
inner_clip(values, name);
|
||||
};
|
||||
|
||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
||||
|
||||
Ok(OutputStream::from(stream))
|
||||
}
|
||||
|
||||
async fn inner_clip(input: Vec<Spanned<Value>>, name: Option<Span>) -> OutputStream {
|
||||
let mut clip_context: ClipboardContext = ClipboardProvider::new().unwrap();
|
||||
let mut new_copy_data = String::new();
|
||||
|
||||
if args.input.len() > 0 {
|
||||
if input.len() > 0 {
|
||||
let mut first = true;
|
||||
for i in args.input.iter() {
|
||||
for i in input.iter() {
|
||||
if !first {
|
||||
new_copy_data.push_str("\n");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
|
||||
let string = i.as_string().map_err(labelled(
|
||||
args.name_span(),
|
||||
let s = i.as_string().map_err(labelled(
|
||||
name,
|
||||
"Given non-string data",
|
||||
"expected strings from pipeline",
|
||||
))?;
|
||||
));
|
||||
|
||||
let string: String = match s {
|
||||
Ok(string) => string,
|
||||
Err(err) => return OutputStream::one(Err(err)),
|
||||
};
|
||||
|
||||
new_copy_data.push_str(&string);
|
||||
}
|
||||
@ -27,5 +73,5 @@ pub fn clip(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
|
||||
clip_context.set_contents(new_copy_data).unwrap();
|
||||
|
||||
Ok(())
|
||||
OutputStream::empty()
|
||||
}
|
||||
|
@ -3,8 +3,9 @@ use crate::errors::ShellError;
|
||||
use crate::evaluate::Scope;
|
||||
use crate::object::Value;
|
||||
use crate::parser::hir;
|
||||
use crate::parser::{registry, Span, Spanned};
|
||||
use crate::parser::{registry, ConfigDeserializer, Span, Spanned};
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
@ -80,6 +81,67 @@ impl CommandArgs {
|
||||
pub fn name_span(&self) -> Option<Span> {
|
||||
self.call_info.name_span
|
||||
}
|
||||
|
||||
pub fn process<'de, T: Deserialize<'de>>(
|
||||
self,
|
||||
registry: &CommandRegistry,
|
||||
callback: fn(T, RunnableContext) -> Result<OutputStream, ShellError>,
|
||||
) -> Result<RunnableArgs<T>, ShellError> {
|
||||
let env = self.env.clone();
|
||||
let args = self.evaluate_once(registry)?;
|
||||
let (input, args) = args.split();
|
||||
let name_span = args.call_info.name_span;
|
||||
let mut deserializer = ConfigDeserializer::from_call_node(args);
|
||||
|
||||
Ok(RunnableArgs {
|
||||
args: T::deserialize(&mut deserializer)?,
|
||||
context: RunnableContext {
|
||||
input: input,
|
||||
env,
|
||||
name: name_span,
|
||||
},
|
||||
callback,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SinkContext {
|
||||
pub input: Vec<Spanned<Value>>,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub name: Option<Span>,
|
||||
}
|
||||
|
||||
pub struct SinkArgs<T> {
|
||||
args: T,
|
||||
context: SinkContext,
|
||||
callback: fn(T, SinkContext) -> Result<(), ShellError>,
|
||||
}
|
||||
|
||||
pub struct RunnableContext {
|
||||
pub input: InputStream,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub name: Option<Span>,
|
||||
}
|
||||
|
||||
impl RunnableContext {
|
||||
pub fn cwd(&self) -> PathBuf {
|
||||
let env = self.env.clone();
|
||||
let env = env.lock().unwrap();
|
||||
|
||||
env.path.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RunnableArgs<T> {
|
||||
args: T,
|
||||
context: RunnableContext,
|
||||
callback: fn(T, RunnableContext) -> Result<OutputStream, ShellError>,
|
||||
}
|
||||
|
||||
impl<T> RunnableArgs<T> {
|
||||
pub fn run(self) -> Result<OutputStream, ShellError> {
|
||||
(self.callback)(self.args, self.context)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EvaluatedStaticCommandArgs {
|
||||
@ -120,6 +182,12 @@ impl EvaluatedStaticCommandArgs {
|
||||
|
||||
(input, args.call_info.args)
|
||||
}
|
||||
|
||||
pub fn split(self) -> (InputStream, EvaluatedCommandArgs) {
|
||||
let EvaluatedStaticCommandArgs { args, input } = self;
|
||||
|
||||
(input, args)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Getters)]
|
||||
@ -155,7 +223,7 @@ impl EvaluatedFilterCommandArgs {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Getters)]
|
||||
#[derive(Getters, new)]
|
||||
#[get = "crate"]
|
||||
pub struct EvaluatedCommandArgs {
|
||||
pub host: Arc<Mutex<dyn Host>>,
|
||||
@ -184,24 +252,21 @@ impl EvaluatedCommandArgs {
|
||||
self.call_info.args.get(name)
|
||||
}
|
||||
|
||||
pub fn slice_from(&self, from: usize) -> Vec<Spanned<Value>> {
|
||||
let positional = &self.call_info.args.positional;
|
||||
|
||||
match positional {
|
||||
None => vec![],
|
||||
Some(list) => list[from..].to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn has(&self, name: &str) -> bool {
|
||||
self.call_info.args.has(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SinkCommandArgs {
|
||||
pub ctx: Context,
|
||||
pub call_info: CallInfo,
|
||||
pub input: Vec<Spanned<Value>>,
|
||||
}
|
||||
|
||||
impl SinkCommandArgs {
|
||||
pub fn name_span(&self) -> Option<Span> {
|
||||
self.call_info.name_span
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum CommandAction {
|
||||
ChangePath(PathBuf),
|
||||
@ -241,38 +306,56 @@ impl ReturnSuccess {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Command: Send + Sync {
|
||||
pub trait StaticCommand: Send + Sync {
|
||||
fn name(&self) -> &str;
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: ®istry::CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError>;
|
||||
fn name(&self) -> &str;
|
||||
|
||||
fn config(&self) -> registry::CommandConfig {
|
||||
registry::CommandConfig {
|
||||
fn signature(&self) -> Signature {
|
||||
Signature {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![],
|
||||
rest_positional: true,
|
||||
named: indexmap::IndexMap::new(),
|
||||
is_filter: true,
|
||||
is_sink: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Sink {
|
||||
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError>;
|
||||
fn name(&self) -> &str;
|
||||
pub enum Command {
|
||||
Static(Arc<dyn StaticCommand>),
|
||||
}
|
||||
|
||||
fn config(&self) -> registry::CommandConfig {
|
||||
registry::CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![],
|
||||
rest_positional: true,
|
||||
named: indexmap::IndexMap::new(),
|
||||
is_filter: false,
|
||||
is_sink: true,
|
||||
impl Command {
|
||||
pub fn name(&self) -> &str {
|
||||
match self {
|
||||
Command::Static(command) => command.name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_sink(&self) -> bool {
|
||||
match self {
|
||||
Command::Static(..) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signature(&self) -> Signature {
|
||||
match self {
|
||||
Command::Static(command) => command.signature(),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: ®istry::CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
match self {
|
||||
Command::Static(command) => command.run(args, registry),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,7 +366,7 @@ pub struct FnFilterCommand {
|
||||
func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
|
||||
}
|
||||
|
||||
impl Command for FnFilterCommand {
|
||||
impl StaticCommand for FnFilterCommand {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
@ -339,7 +422,11 @@ pub struct FnRawCommand {
|
||||
>,
|
||||
}
|
||||
|
||||
impl Command for FnRawCommand {
|
||||
impl StaticCommand for FnRawCommand {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
@ -347,10 +434,6 @@ impl Command for FnRawCommand {
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
(self.func)(args, registry)
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command(
|
||||
@ -360,45 +443,24 @@ pub fn command(
|
||||
+ Send
|
||||
+ Sync,
|
||||
>,
|
||||
) -> Arc<dyn Command> {
|
||||
Arc::new(FnRawCommand {
|
||||
) -> Arc<Command> {
|
||||
Arc::new(Command::Static(Arc::new(FnRawCommand {
|
||||
name: name.to_string(),
|
||||
func,
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
||||
pub fn static_command(command: impl StaticCommand + 'static) -> Arc<Command> {
|
||||
Arc::new(Command::Static(Arc::new(command)))
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn filter(
|
||||
name: &str,
|
||||
func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
|
||||
) -> Arc<dyn Command> {
|
||||
Arc::new(FnFilterCommand {
|
||||
) -> Arc<Command> {
|
||||
Arc::new(Command::Static(Arc::new(FnFilterCommand {
|
||||
name: name.to_string(),
|
||||
func,
|
||||
})
|
||||
}
|
||||
|
||||
pub struct FnSink {
|
||||
name: String,
|
||||
func: Box<dyn Fn(SinkCommandArgs) -> Result<(), ShellError>>,
|
||||
}
|
||||
|
||||
impl Sink for FnSink {
|
||||
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
(self.func)(args)
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sink(
|
||||
name: &str,
|
||||
func: Box<dyn Fn(SinkCommandArgs) -> Result<(), ShellError>>,
|
||||
) -> Arc<dyn Sink> {
|
||||
Arc::new(FnSink {
|
||||
name: name.to_string(),
|
||||
func,
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
@ -1,57 +1,61 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::commands::EvaluatedStaticCommandArgs;
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{config, Value};
|
||||
use crate::parser::hir::SyntaxType;
|
||||
use crate::parser::registry::{self, CommandConfig, NamedType};
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use crate::parser::registry::{self};
|
||||
use std::iter::FromIterator;
|
||||
|
||||
pub struct Config;
|
||||
|
||||
impl Command for Config {
|
||||
#[derive(Deserialize)]
|
||||
pub struct ConfigArgs {
|
||||
set: Option<(Spanned<String>, Spanned<Value>)>,
|
||||
get: Option<Spanned<String>>,
|
||||
clear: Spanned<bool>,
|
||||
remove: Option<Spanned<String>>,
|
||||
path: Spanned<bool>,
|
||||
}
|
||||
|
||||
impl StaticCommand for Config {
|
||||
fn name(&self) -> &str {
|
||||
"config"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("config")
|
||||
.named("set", SyntaxType::Any)
|
||||
.named("get", SyntaxType::Any)
|
||||
.named("remove", SyntaxType::Any)
|
||||
.switch("clear")
|
||||
.switch("path")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: ®istry::CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once(registry)?;
|
||||
config(args)
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"config"
|
||||
}
|
||||
|
||||
fn config(&self) -> CommandConfig {
|
||||
let mut named: IndexMap<String, NamedType> = IndexMap::new();
|
||||
named.insert("set".to_string(), NamedType::Optional(SyntaxType::Any));
|
||||
named.insert("get".to_string(), NamedType::Optional(SyntaxType::Any));
|
||||
named.insert("clear".to_string(), NamedType::Switch);
|
||||
|
||||
named.insert("remove".to_string(), NamedType::Optional(SyntaxType::Any));
|
||||
|
||||
CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![],
|
||||
rest_positional: false,
|
||||
named,
|
||||
is_sink: true,
|
||||
is_filter: false,
|
||||
}
|
||||
args.process(registry, config)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut result = crate::object::config::config(args.name_span())?;
|
||||
pub fn config(
|
||||
ConfigArgs {
|
||||
set,
|
||||
get,
|
||||
clear,
|
||||
remove,
|
||||
path,
|
||||
}: ConfigArgs,
|
||||
RunnableContext { name, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut result = crate::object::config::config(name)?;
|
||||
|
||||
trace!("{:#?}", args.call_args().positional);
|
||||
trace!("{:#?}", args.call_args().named);
|
||||
|
||||
if let Some(v) = args.get("get") {
|
||||
let key = v.as_string()?;
|
||||
if let Some(v) = get {
|
||||
let key = v.to_string();
|
||||
let value = result
|
||||
.get(&key)
|
||||
.ok_or_else(|| ShellError::string(&format!("Missing key {} in config", key)))?;
|
||||
@ -61,31 +65,38 @@ pub fn config(args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellErr
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(v) = args.get("set") {
|
||||
if let Ok((key, value)) = v.as_pair() {
|
||||
result.insert(key.as_string()?.to_string(), value.clone());
|
||||
if let Some((key, value)) = set {
|
||||
result.insert(key.to_string(), value.clone());
|
||||
|
||||
config::write_config(&result)?;
|
||||
config::write_config(&result)?;
|
||||
|
||||
return Ok(
|
||||
stream![Spanned::from_item(Value::Object(result.into()), v.span())]
|
||||
.from_input_stream(),
|
||||
);
|
||||
}
|
||||
return Ok(stream![Spanned::from_item(
|
||||
Value::Object(result.into()),
|
||||
value.span()
|
||||
)]
|
||||
.from_input_stream());
|
||||
}
|
||||
|
||||
if let Some(c) = args.get("clear") {
|
||||
if let Spanned { item: true, span } = clear {
|
||||
result.clear();
|
||||
|
||||
config::write_config(&result)?;
|
||||
|
||||
return Ok(
|
||||
stream![Spanned::from_item(Value::Object(result.into()), c.span())].from_input_stream(),
|
||||
stream![Spanned::from_item(Value::Object(result.into()), span)].from_input_stream(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(v) = args.get("remove") {
|
||||
let key = v.as_string()?;
|
||||
if let Spanned { item: true, span } = path {
|
||||
let path = config::config_path()?;
|
||||
|
||||
return Ok(
|
||||
stream![Value::Primitive(Primitive::Path(path)).spanned(span)].from_input_stream(),
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(v) = remove {
|
||||
let key = v.to_string();
|
||||
|
||||
if result.contains_key(&key) {
|
||||
result.remove(&key);
|
||||
@ -96,13 +107,9 @@ pub fn config(args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellErr
|
||||
)));
|
||||
}
|
||||
|
||||
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).spanned(v)]);
|
||||
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).spanned(v.span())]);
|
||||
return Ok(obj.from_input_stream());
|
||||
}
|
||||
|
||||
if args.len() == 0 {
|
||||
return Ok(vec![Value::Object(result.into()).spanned(args.name_span())].into());
|
||||
}
|
||||
|
||||
Err(ShellError::string(format!("Unimplemented")))
|
||||
return Ok(vec![Value::Object(result.into()).spanned(name)].into());
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::object::base::OF64;
|
||||
use crate::object::{Primitive, SpannedDictBuilder, Value};
|
||||
use crate::prelude::*;
|
||||
|
||||
fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spanned<Value> {
|
||||
pub fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spanned<Value> {
|
||||
let span = span.into();
|
||||
|
||||
match v {
|
||||
|
@ -1,9 +1,33 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::Value;
|
||||
use crate::parser::Span;
|
||||
use crate::prelude::*;
|
||||
|
||||
fn get_member(path: &str, span: Span, obj: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
|
||||
pub struct Get;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetArgs {
|
||||
rest: Vec<Spanned<String>>,
|
||||
}
|
||||
|
||||
impl StaticCommand for Get {
|
||||
fn name(&self) -> &str {
|
||||
"get"
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, get)?.run()
|
||||
}
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("get").rest()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_member(path: &Spanned<String>, obj: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
|
||||
let mut current = obj;
|
||||
for p in path.split(".") {
|
||||
match current.get_data_by_key(p) {
|
||||
@ -12,7 +36,7 @@ fn get_member(path: &str, span: Span, obj: &Spanned<Value>) -> Result<Spanned<Va
|
||||
return Err(ShellError::labeled_error(
|
||||
"Unknown field",
|
||||
"object missing field",
|
||||
span,
|
||||
path.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -21,42 +45,21 @@ fn get_member(path: &str, span: Span, obj: &Spanned<Value>) -> Result<Spanned<Va
|
||||
Ok(current.clone())
|
||||
}
|
||||
|
||||
pub fn get(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let span = args.name_span();
|
||||
let len = args.len();
|
||||
|
||||
if len == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Get requires a field or field path",
|
||||
"needs parameter",
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
let amount = args.expect_nth(0)?.as_i64();
|
||||
let (input, args) = args.parts();
|
||||
let positional = args.positional;
|
||||
|
||||
pub fn get(
|
||||
GetArgs { rest: fields }: GetArgs,
|
||||
RunnableContext { input, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
// If it's a number, get the row instead of the column
|
||||
if let Ok(amount) = amount {
|
||||
return Ok(input.values.skip(amount as u64).take(1).from_input_stream());
|
||||
}
|
||||
|
||||
let fields: Result<Vec<(String, Span)>, _> = positional
|
||||
.iter()
|
||||
.flatten()
|
||||
.map(|a| (a.as_string().map(|x| (x, a.span))))
|
||||
.collect();
|
||||
|
||||
let fields = fields?;
|
||||
// if let Some(amount) = amount {
|
||||
// return Ok(input.values.skip(amount as u64).take(1).from_input_stream());
|
||||
// }
|
||||
|
||||
let stream = input
|
||||
.values
|
||||
.map(move |item| {
|
||||
let mut result = VecDeque::new();
|
||||
for field in &fields {
|
||||
match get_member(&field.0, field.1, &item) {
|
||||
match get_member(field, &item) {
|
||||
Ok(Spanned {
|
||||
item: Value::List(l),
|
||||
..
|
||||
|
@ -12,7 +12,7 @@ macro_rules! command {
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($number:tt)* }
|
||||
Rest {}
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -52,8 +52,8 @@ macro_rules! command {
|
||||
stringify!($config_name)
|
||||
}
|
||||
|
||||
fn config(&self) -> $crate::parser::registry::CommandConfig {
|
||||
$crate::parser::registry::CommandConfig {
|
||||
fn config(&self) -> $crate::parser::registry::Signature {
|
||||
$crate::parser::registry::Signature {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![$($mandatory_positional)*],
|
||||
rest_positional: false,
|
||||
@ -82,7 +82,7 @@ macro_rules! command {
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident : Switch , $($rest:tt)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -102,7 +102,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
@ -132,7 +132,7 @@ macro_rules! command {
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -152,7 +152,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
@ -182,7 +182,7 @@ macro_rules! command {
|
||||
Named { $export:tt $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -202,7 +202,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* ],
|
||||
optional_positional: vec![ $($optional_positional)* ],
|
||||
@ -232,7 +232,7 @@ macro_rules! command {
|
||||
Named { $export:ident $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { $param_name:ident : Block , $($rest:tt)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -255,7 +255,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory_block(
|
||||
stringify!($param_name)
|
||||
@ -287,7 +287,7 @@ macro_rules! command {
|
||||
Named { $export:ident $args:ident $body:block }
|
||||
Positional { $($positional_count:tt)* }
|
||||
Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name:tt,
|
||||
mandatory_positional: vec![ $($mandatory_positional:tt)* ],
|
||||
optional_positional: vec![ $($optional_positional:tt)* ],
|
||||
@ -310,7 +310,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { $($positional_count)* + 1 }
|
||||
Rest { $($rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory(
|
||||
stringify!($param_name), <$param_kind>::syntax_type()
|
||||
@ -341,7 +341,7 @@ macro_rules! command {
|
||||
Named { $export $args $body }
|
||||
Positional { 0 }
|
||||
Rest { $($command_rest)* }
|
||||
CommandConfig {
|
||||
Signature {
|
||||
name: $config_name,
|
||||
mandatory_positional: vec![],
|
||||
optional_positional: vec![],
|
||||
@ -377,11 +377,11 @@ macro_rules! command {
|
||||
// stringify!($name)
|
||||
// }
|
||||
|
||||
// fn config(&self) -> CommandConfig {
|
||||
// fn config(&self) -> Signature {
|
||||
// let mut named: IndexMap<String, NamedType> = IndexMap::new();
|
||||
// named.insert(stringify!($param).to_string(), NamedType::$kind);
|
||||
|
||||
// CommandConfig {
|
||||
// Signature {
|
||||
// name: self.name().to_string(),
|
||||
// mandatory_positional: vec![],
|
||||
// optional_positional: vec![],
|
||||
|
@ -1,9 +1,10 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::context::SpanSource;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{Primitive, Value};
|
||||
use crate::parser::hir::SyntaxType;
|
||||
use crate::parser::parse::span::Span;
|
||||
use crate::parser::registry::{self, CommandConfig, NamedType};
|
||||
use crate::parser::registry::{self, Signature};
|
||||
use crate::prelude::*;
|
||||
use mime::Mime;
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -12,75 +13,81 @@ use uuid::Uuid;
|
||||
|
||||
pub struct Open;
|
||||
|
||||
impl Command for Open {
|
||||
#[derive(Deserialize)]
|
||||
pub struct OpenArgs {
|
||||
path: Spanned<PathBuf>,
|
||||
raw: bool,
|
||||
}
|
||||
|
||||
impl StaticCommand for Open {
|
||||
fn name(&self) -> &str {
|
||||
"open"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name())
|
||||
.required("path", SyntaxType::Block)
|
||||
.switch("raw")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: ®istry::CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let env = args.env.clone();
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let path = <Spanned<PathBuf>>::extract(args.expect_nth(0)?)?;
|
||||
let raw = args.has("raw");
|
||||
args.process(registry, run)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
let span = args.name_span();
|
||||
fn run(
|
||||
OpenArgs { raw, path }: OpenArgs,
|
||||
RunnableContext { env, name, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let cwd = env.lock().unwrap().path().to_path_buf();
|
||||
let full_path = PathBuf::from(cwd);
|
||||
|
||||
let cwd = env.lock().unwrap().path().to_path_buf();
|
||||
let full_path = PathBuf::from(cwd);
|
||||
let path_str = path.to_str().ok_or(ShellError::type_error(
|
||||
"Path",
|
||||
"invalid path".spanned(path.span),
|
||||
))?;
|
||||
|
||||
let path_str = path.to_str().ok_or(ShellError::type_error(
|
||||
"Path",
|
||||
"invalid path".spanned(path.span),
|
||||
))?;
|
||||
let (file_extension, contents, contents_span, span_source) =
|
||||
fetch(&full_path, path_str, path.span)?;
|
||||
|
||||
let (file_extension, contents, contents_span, span_source) =
|
||||
fetch(&full_path, path_str, path.span)?;
|
||||
let file_extension = if raw { None } else { file_extension };
|
||||
|
||||
let file_extension = if raw { None } else { file_extension };
|
||||
let mut stream = VecDeque::new();
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
if let Some(uuid) = contents_span.source {
|
||||
// If we have loaded something, track its source
|
||||
stream.push_back(ReturnSuccess::action(CommandAction::AddSpanSource(
|
||||
uuid,
|
||||
span_source,
|
||||
)))
|
||||
}
|
||||
|
||||
if let Some(uuid) = contents_span.source {
|
||||
// If we have loaded something, track its source
|
||||
stream.push_back(ReturnSuccess::action(CommandAction::AddSpanSource(
|
||||
uuid,
|
||||
span_source,
|
||||
)))
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) => {
|
||||
let value = parse_as_value(file_extension, string, contents_span, name)?;
|
||||
|
||||
match value {
|
||||
Spanned {
|
||||
item: Value::List(list),
|
||||
..
|
||||
} => {
|
||||
for elem in list {
|
||||
stream.push_back(ReturnSuccess::value(elem));
|
||||
}
|
||||
}
|
||||
x => stream.push_back(ReturnSuccess::value(x)),
|
||||
}
|
||||
}
|
||||
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) => {
|
||||
let value = parse_as_value(file_extension, string, contents_span, span)?;
|
||||
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
|
||||
};
|
||||
|
||||
match value {
|
||||
Spanned {
|
||||
item: Value::List(list),
|
||||
..
|
||||
} => {
|
||||
for elem in list {
|
||||
stream.push_back(ReturnSuccess::value(elem));
|
||||
}
|
||||
}
|
||||
x => stream.push_back(ReturnSuccess::value(x)),
|
||||
}
|
||||
}
|
||||
|
||||
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
|
||||
};
|
||||
|
||||
Ok(stream.boxed().to_output_stream())
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"open"
|
||||
}
|
||||
|
||||
fn config(&self) -> CommandConfig {
|
||||
CommandConfig::new(self.name())
|
||||
.required("path", SyntaxType::Block)
|
||||
.named("raw", NamedType::Switch)
|
||||
.sink()
|
||||
}
|
||||
Ok(stream.boxed().to_output_stream())
|
||||
}
|
||||
|
||||
// command! {
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::registry;
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use futures_async_stream::async_stream_block;
|
||||
use serde::{self, Deserialize, Serialize};
|
||||
use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
@ -37,10 +39,18 @@ pub enum NuResult {
|
||||
pub struct PluginCommand {
|
||||
name: String,
|
||||
path: String,
|
||||
config: registry::CommandConfig,
|
||||
config: registry::Signature,
|
||||
}
|
||||
|
||||
impl Command for PluginCommand {
|
||||
impl StaticCommand for PluginCommand {
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn signature(&self) -> registry::Signature {
|
||||
self.config.clone()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
@ -48,29 +58,36 @@ impl Command for PluginCommand {
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
filter_plugin(self.path.clone(), args, registry)
|
||||
}
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
fn config(&self) -> registry::CommandConfig {
|
||||
self.config.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(new)]
|
||||
pub struct PluginSink {
|
||||
name: String,
|
||||
path: String,
|
||||
config: registry::CommandConfig,
|
||||
config: registry::Signature,
|
||||
}
|
||||
|
||||
impl Sink for PluginSink {
|
||||
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
sink_plugin(self.path.clone(), args)
|
||||
impl StaticCommand for PluginSink {
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let path = self.path.clone();
|
||||
|
||||
let stream = async_stream_block! {
|
||||
sink_plugin(path, args).await;
|
||||
};
|
||||
|
||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
||||
|
||||
Ok(OutputStream::from(stream))
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
&self.config.name
|
||||
}
|
||||
fn config(&self) -> registry::CommandConfig {
|
||||
|
||||
fn signature(&self) -> registry::Signature {
|
||||
self.config.clone()
|
||||
}
|
||||
}
|
||||
@ -191,9 +208,10 @@ pub fn filter_plugin(
|
||||
Ok(stream.to_output_stream())
|
||||
}
|
||||
|
||||
pub fn sink_plugin(path: String, args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
pub async fn sink_plugin(path: String, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
//use subprocess::Exec;
|
||||
let request = JsonRpc::new("sink", (args.call_info, args.input));
|
||||
let input: Vec<Spanned<Value>> = args.input.values.collect().await;
|
||||
let request = JsonRpc::new("sink", (args.call_info, input));
|
||||
let request_raw = serde_json::to_string(&request).unwrap();
|
||||
let mut tmpfile = tempfile::NamedTempFile::new()?;
|
||||
let _ = writeln!(tmpfile, "{}", request_raw);
|
||||
@ -206,5 +224,5 @@ pub fn sink_plugin(path: String, args: SinkCommandArgs) -> Result<(), ShellError
|
||||
|
||||
let _ = child.wait();
|
||||
|
||||
Ok(())
|
||||
Ok(OutputStream::empty())
|
||||
}
|
||||
|
@ -1,63 +1,57 @@
|
||||
use crate::commands::EvaluatedStaticCommandArgs;
|
||||
use crate::commands::{EvaluatedStaticCommandArgs, StaticCommand};
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::hir::SyntaxType;
|
||||
use crate::parser::registry::{CommandConfig, NamedType, PositionalType};
|
||||
use crate::parser::registry::{NamedType, PositionalType};
|
||||
use crate::prelude::*;
|
||||
use indexmap::IndexMap;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct Remove;
|
||||
|
||||
impl Command for Remove {
|
||||
#[derive(Deserialize)]
|
||||
pub struct RemoveArgs {
|
||||
path: Spanned<PathBuf>,
|
||||
recursive: bool,
|
||||
}
|
||||
|
||||
impl StaticCommand for Remove {
|
||||
fn name(&self) -> &str {
|
||||
"rm"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("rm")
|
||||
.required("path", SyntaxType::Path)
|
||||
.switch("recursive")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let env = args.env.clone();
|
||||
rm(args.evaluate_once(registry)?, env)
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"rm"
|
||||
}
|
||||
|
||||
fn config(&self) -> CommandConfig {
|
||||
let mut named: IndexMap<String, NamedType> = IndexMap::new();
|
||||
named.insert("recursive".to_string(), NamedType::Switch);
|
||||
|
||||
CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![PositionalType::mandatory("file", SyntaxType::Path)],
|
||||
rest_positional: false,
|
||||
named,
|
||||
is_sink: true,
|
||||
is_filter: false,
|
||||
}
|
||||
args.process(registry, rm)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rm(
|
||||
args: EvaluatedStaticCommandArgs,
|
||||
env: Arc<Mutex<Environment>>,
|
||||
RemoveArgs { path, recursive }: RemoveArgs,
|
||||
context: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut full_path = env.lock().unwrap().path().to_path_buf();
|
||||
let mut full_path = context.cwd();
|
||||
|
||||
match args
|
||||
.nth(0)
|
||||
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
|
||||
.as_string()?
|
||||
.as_str()
|
||||
{
|
||||
match path.item.to_str().unwrap() {
|
||||
"." | ".." => return Err(ShellError::string("\".\" and \"..\" may not be removed")),
|
||||
file => full_path.push(file),
|
||||
}
|
||||
|
||||
if full_path.is_dir() {
|
||||
if !args.has("recursive") {
|
||||
return Err(ShellError::labeled_error(
|
||||
if !recursive {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"is a directory",
|
||||
"",
|
||||
args.name_span().unwrap(),
|
||||
context.name,
|
||||
));
|
||||
}
|
||||
std::fs::remove_dir_all(&full_path).expect("can not remove directory");
|
||||
|
@ -1,100 +1,119 @@
|
||||
use crate::commands::command::SinkCommandArgs;
|
||||
use crate::commands::to_csv::{to_string as to_csv_to_string, value_to_csv_value};
|
||||
use crate::commands::to_json::value_to_json_value;
|
||||
use crate::commands::to_toml::value_to_toml_value;
|
||||
use crate::commands::to_yaml::value_to_yaml_value;
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{Primitive, Value};
|
||||
use crate::parser::Spanned;
|
||||
use crate::prelude::*;
|
||||
use futures_async_stream::async_stream_block;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
if args.call_info.args.positional.is_none() {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Save requires a filepath",
|
||||
"needs path",
|
||||
args.name_span(),
|
||||
));
|
||||
}
|
||||
pub struct Save;
|
||||
|
||||
let positional = match args.call_info.args.positional {
|
||||
None => return Err(ShellError::string("save requires a filepath")),
|
||||
Some(p) => p,
|
||||
};
|
||||
|
||||
let cwd = args.ctx.env.lock().unwrap().path().to_path_buf();
|
||||
let mut full_path = PathBuf::from(cwd);
|
||||
match &(positional[0].item) {
|
||||
Value::Primitive(Primitive::String(s)) => full_path.push(Path::new(s)),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let save_raw = match positional.get(1) {
|
||||
Some(Spanned {
|
||||
item: Value::Primitive(Primitive::String(s)),
|
||||
..
|
||||
}) if s == "--raw" => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let contents = match full_path.extension() {
|
||||
Some(x) if x == "csv" && !save_raw => {
|
||||
if args.input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to csv requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
to_csv_to_string(&value_to_csv_value(&args.input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "toml" && !save_raw => {
|
||||
if args.input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to toml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
toml::to_string(&value_to_toml_value(&args.input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "json" && !save_raw => {
|
||||
if args.input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to json requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_json::to_string(&value_to_json_value(&args.input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "yml" && !save_raw => {
|
||||
if args.input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to yml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "yaml" && !save_raw => {
|
||||
if args.input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to yaml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap()
|
||||
}
|
||||
_ => {
|
||||
let mut save_data = String::new();
|
||||
if args.input.len() > 0 {
|
||||
let mut first = true;
|
||||
for i in args.input.iter() {
|
||||
if !first {
|
||||
save_data.push_str("\n");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
save_data.push_str(&i.as_string().unwrap());
|
||||
}
|
||||
}
|
||||
save_data
|
||||
}
|
||||
};
|
||||
|
||||
let _ = std::fs::write(full_path, contents);
|
||||
Ok(())
|
||||
#[derive(Deserialize)]
|
||||
struct SaveArgs {
|
||||
path: Spanned<PathBuf>,
|
||||
raw: bool,
|
||||
}
|
||||
|
||||
impl StaticCommand for Save {
|
||||
fn name(&self) -> &str {
|
||||
"save"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("save")
|
||||
.required("path", SyntaxType::Path)
|
||||
.switch("raw")
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
args.process(registry, save)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn save(
|
||||
SaveArgs {
|
||||
path,
|
||||
raw: save_raw,
|
||||
}: SaveArgs,
|
||||
context: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let mut full_path = context.cwd();
|
||||
full_path.push(path.item());
|
||||
|
||||
let stream = async_stream_block! {
|
||||
let input: Vec<Spanned<Value>> = context.input.values.collect().await;
|
||||
|
||||
let contents = match full_path.extension() {
|
||||
Some(x) if x == "csv" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to csv requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
to_csv_to_string(&value_to_csv_value(&input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "toml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to toml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
toml::to_string(&value_to_toml_value(&input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "json" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to json requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_json::to_string(&value_to_json_value(&input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "yml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to yml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_yaml::to_string(&value_to_yaml_value(&input[0])).unwrap()
|
||||
}
|
||||
Some(x) if x == "yaml" && !save_raw => {
|
||||
if input.len() != 1 {
|
||||
return Err(ShellError::string(
|
||||
"saving to yaml requires a single object (or use --raw)",
|
||||
));
|
||||
}
|
||||
serde_yaml::to_string(&value_to_yaml_value(&input[0])).unwrap()
|
||||
}
|
||||
_ => {
|
||||
let mut save_data = String::new();
|
||||
if input.len() > 0 {
|
||||
let mut first = true;
|
||||
for i in input.iter() {
|
||||
if !first {
|
||||
save_data.push_str("\n");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
save_data.push_str(&i.as_string().unwrap());
|
||||
}
|
||||
}
|
||||
save_data
|
||||
}
|
||||
};
|
||||
|
||||
let _ = std::fs::write(full_path, contents);
|
||||
};
|
||||
|
||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
||||
|
||||
Ok(OutputStream::from(stream))
|
||||
}
|
||||
|
@ -1,54 +1,40 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::parser::registry::CommandConfig;
|
||||
use crate::parser::registry::PositionalType;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub struct SkipWhile;
|
||||
|
||||
impl Command for SkipWhile {
|
||||
#[derive(Deserialize)]
|
||||
pub struct SkipWhileArgs {
|
||||
condition: value::Block,
|
||||
}
|
||||
|
||||
impl StaticCommand for SkipWhile {
|
||||
fn name(&self) -> &str {
|
||||
"skip-while"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("skip-while")
|
||||
.required("condition", SyntaxType::Block)
|
||||
.filter()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
skip_while(args, registry)
|
||||
}
|
||||
fn name(&self) -> &str {
|
||||
"skip-while"
|
||||
}
|
||||
|
||||
fn config(&self) -> CommandConfig {
|
||||
CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![PositionalType::mandatory_block("condition")],
|
||||
rest_positional: false,
|
||||
named: indexmap::IndexMap::new(),
|
||||
is_filter: true,
|
||||
is_sink: false,
|
||||
}
|
||||
args.process(registry, skip_while)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn skip_while(
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
SkipWhileArgs { condition }: SkipWhileArgs,
|
||||
RunnableContext { input, .. }: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let block = args.expect_nth(0)?.as_block()?;
|
||||
let span = args.name_span();
|
||||
let len = args.len();
|
||||
let input = args.input;
|
||||
|
||||
if len == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Where requires a condition",
|
||||
"needs condition",
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
let objects = input.values.skip_while(move |item| {
|
||||
let result = block.invoke(&item);
|
||||
let result = condition.invoke(&item);
|
||||
|
||||
let return_value = match result {
|
||||
Ok(v) if v.is_true() => true,
|
||||
|
@ -1,9 +1,8 @@
|
||||
use crate::commands::command::SinkCommandArgs;
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::TableView;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn table(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
pub fn table(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
let mut host = args.ctx.host.lock().unwrap();
|
||||
let view = TableView::from_list(&args.input);
|
||||
|
@ -1,9 +1,8 @@
|
||||
use crate::commands::command::SinkCommandArgs;
|
||||
use crate::errors::ShellError;
|
||||
use crate::format::VTableView;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn vtable(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
pub fn vtable(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
|
||||
if args.input.len() > 0 {
|
||||
let mut host = args.ctx.host.lock().unwrap();
|
||||
let view = VTableView::from_list(&args.input);
|
||||
|
@ -1,75 +1,58 @@
|
||||
use crate::commands::StaticCommand;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::base as value;
|
||||
use crate::parser::hir::SyntaxType;
|
||||
use crate::parser::registry::{self, CommandConfig, PositionalType};
|
||||
use crate::parser::registry;
|
||||
use crate::prelude::*;
|
||||
|
||||
use futures::future::ready;
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub struct Where;
|
||||
|
||||
impl Command for Where {
|
||||
#[derive(Deserialize)]
|
||||
struct WhereArgs {
|
||||
condition: value::Block,
|
||||
}
|
||||
|
||||
impl StaticCommand for Where {
|
||||
fn name(&self) -> &str {
|
||||
"where"
|
||||
}
|
||||
|
||||
fn signature(&self) -> registry::Signature {
|
||||
Signature::build("where")
|
||||
.required("condition", SyntaxType::Block)
|
||||
.sink()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: ®istry::CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let args = args.evaluate_once(registry)?;
|
||||
let condition = value::Block::extract(args.expect_nth(0)?)?;
|
||||
let input = args.input;
|
||||
let input: InputStream =
|
||||
trace_stream!(target: "nu::trace_stream::where", "where input" = input);
|
||||
|
||||
Ok(input
|
||||
.values
|
||||
.filter_map(move |item| {
|
||||
let result = condition.invoke(&item);
|
||||
|
||||
let return_value = match result {
|
||||
Err(err) => Some(Err(err)),
|
||||
Ok(v) if v.is_true() => Some(Ok(ReturnSuccess::Value(item.clone()))),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
ready(return_value)
|
||||
})
|
||||
.boxed()
|
||||
.to_output_stream())
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"where"
|
||||
}
|
||||
|
||||
fn config(&self) -> CommandConfig {
|
||||
CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![PositionalType::mandatory("condition", SyntaxType::Block)],
|
||||
rest_positional: false,
|
||||
named: IndexMap::default(),
|
||||
is_sink: true,
|
||||
is_filter: false,
|
||||
}
|
||||
args.process(registry, run)?.run()
|
||||
}
|
||||
}
|
||||
|
||||
// command! {
|
||||
// Where as where(args, condition: Block,) {
|
||||
// let input = args.input;
|
||||
// let input: InputStream = trace_stream!(target: "nu::trace_stream::where", "where input" = input);
|
||||
fn run(
|
||||
WhereArgs { condition }: WhereArgs,
|
||||
context: RunnableContext,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
Ok(context
|
||||
.input
|
||||
.values
|
||||
.filter_map(move |item| {
|
||||
let result = condition.invoke(&item);
|
||||
|
||||
// input.values.filter_map(move |item| {
|
||||
// let result = condition.invoke(&item);
|
||||
let return_value = match result {
|
||||
Err(err) => Some(Err(err)),
|
||||
Ok(v) if v.is_true() => Some(Ok(ReturnSuccess::Value(item.clone()))),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
// let return_value = match result {
|
||||
// Err(err) => Some(Err(err)),
|
||||
// Ok(v) if v.is_true() => Some(Ok(ReturnSuccess::Value(item.clone()))),
|
||||
// _ => None,
|
||||
// };
|
||||
|
||||
// ready(return_value)
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
ready(return_value)
|
||||
})
|
||||
.boxed()
|
||||
.to_output_stream())
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::commands::command::{CallInfo, Sink, SinkCommandArgs, UnevaluatedCallInfo};
|
||||
use crate::commands::{CallInfo, Command, StaticCommand, UnevaluatedCallInfo};
|
||||
use crate::parser::{hir, registry, Span};
|
||||
use crate::prelude::*;
|
||||
|
||||
@ -37,7 +37,7 @@ impl SourceMap {
|
||||
#[derive(Clone, new)]
|
||||
pub struct CommandRegistry {
|
||||
#[new(value = "Arc::new(Mutex::new(IndexMap::default()))")]
|
||||
registry: Arc<Mutex<IndexMap<String, Arc<dyn Command>>>>,
|
||||
registry: Arc<Mutex<IndexMap<String, Arc<Command>>>>,
|
||||
}
|
||||
|
||||
impl CommandRegistry {
|
||||
@ -47,7 +47,7 @@ impl CommandRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_command(&self, name: &str) -> Option<Arc<dyn Command>> {
|
||||
fn get_command(&self, name: &str) -> Option<Arc<Command>> {
|
||||
let registry = self.registry.lock().unwrap();
|
||||
|
||||
registry.get(name).map(|c| c.clone())
|
||||
@ -59,7 +59,7 @@ impl CommandRegistry {
|
||||
registry.contains_key(name)
|
||||
}
|
||||
|
||||
fn insert(&mut self, name: impl Into<String>, command: Arc<dyn Command>) {
|
||||
fn insert(&mut self, name: impl Into<String>, command: Arc<Command>) {
|
||||
let mut registry = self.registry.lock().unwrap();
|
||||
registry.insert(name.into(), command);
|
||||
}
|
||||
@ -73,7 +73,6 @@ impl CommandRegistry {
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
registry: CommandRegistry,
|
||||
sinks: IndexMap<String, Arc<dyn Sink>>,
|
||||
crate source_map: SourceMap,
|
||||
crate host: Arc<Mutex<dyn Host + Send>>,
|
||||
crate env: Arc<Mutex<Environment>>,
|
||||
@ -87,57 +86,22 @@ impl Context {
|
||||
crate fn basic() -> Result<Context, Box<dyn Error>> {
|
||||
Ok(Context {
|
||||
registry: CommandRegistry::new(),
|
||||
sinks: indexmap::IndexMap::new(),
|
||||
source_map: SourceMap::new(),
|
||||
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
|
||||
env: Arc::new(Mutex::new(Environment::basic()?)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn add_commands(&mut self, commands: Vec<Arc<dyn Command>>) {
|
||||
pub fn add_commands(&mut self, commands: Vec<Arc<Command>>) {
|
||||
for command in commands {
|
||||
self.registry.insert(command.name().to_string(), command);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_sinks(&mut self, sinks: Vec<Arc<dyn Sink>>) {
|
||||
for sink in sinks {
|
||||
self.sinks.insert(sink.name().to_string(), sink);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_span_source(&mut self, uuid: Uuid, span_source: SpanSource) {
|
||||
self.source_map.insert(uuid, span_source);
|
||||
}
|
||||
|
||||
crate fn has_sink(&self, name: &str) -> bool {
|
||||
self.sinks.contains_key(name)
|
||||
}
|
||||
|
||||
crate fn get_sink(&self, name: &str) -> Arc<dyn Sink> {
|
||||
self.sinks.get(name).unwrap().clone()
|
||||
}
|
||||
|
||||
crate fn run_sink(
|
||||
&mut self,
|
||||
command: Arc<dyn Sink>,
|
||||
name_span: Option<Span>,
|
||||
args: registry::EvaluatedArgs,
|
||||
input: Vec<Spanned<Value>>,
|
||||
) -> Result<(), ShellError> {
|
||||
let command_args = SinkCommandArgs {
|
||||
ctx: self.clone(),
|
||||
call_info: CallInfo {
|
||||
name_span,
|
||||
source_map: self.source_map.clone(),
|
||||
args,
|
||||
},
|
||||
input,
|
||||
};
|
||||
|
||||
command.run(command_args)
|
||||
}
|
||||
|
||||
pub fn clone_commands(&self) -> CommandRegistry {
|
||||
self.registry.clone()
|
||||
}
|
||||
@ -146,13 +110,13 @@ impl Context {
|
||||
self.registry.has(name)
|
||||
}
|
||||
|
||||
crate fn get_command(&self, name: &str) -> Arc<dyn Command> {
|
||||
crate fn get_command(&self, name: &str) -> Arc<Command> {
|
||||
self.registry.get_command(name).unwrap()
|
||||
}
|
||||
|
||||
crate fn run_command(
|
||||
crate async fn run_command(
|
||||
&mut self,
|
||||
command: Arc<dyn Command>,
|
||||
command: Arc<Command>,
|
||||
name_span: Option<Span>,
|
||||
source_map: SourceMap,
|
||||
args: hir::Call,
|
||||
@ -161,7 +125,7 @@ impl Context {
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let command_args = self.command_args(args, input, source, source_map, name_span);
|
||||
|
||||
command.run(command_args, self.registry())
|
||||
command.run(command_args, self.registry()).await
|
||||
}
|
||||
|
||||
fn call_info(
|
||||
|
@ -62,6 +62,15 @@ pub struct ShellError {
|
||||
cause: Option<Box<ProximateShellError>>,
|
||||
}
|
||||
|
||||
impl serde::de::Error for ShellError {
|
||||
fn custom<T>(msg: T) -> Self
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
ShellError::string(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ShellError {
|
||||
crate fn type_error(
|
||||
expected: impl Into<String>,
|
||||
@ -351,16 +360,6 @@ impl std::convert::From<std::io::Error> for ShellError {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<futures_sink::VecSinkError> for ShellError {
|
||||
fn from(_input: futures_sink::VecSinkError) -> ShellError {
|
||||
ProximateShellError::String(StringError {
|
||||
title: format!("Unexpected Vec Sink Error"),
|
||||
error: Value::nothing(),
|
||||
})
|
||||
.start()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::convert::From<subprocess::PopenError> for ShellError {
|
||||
fn from(input: subprocess::PopenError) -> ShellError {
|
||||
ProximateShellError::String(StringError {
|
||||
|
@ -55,6 +55,16 @@ crate fn evaluate_baseline_expr(
|
||||
)),
|
||||
}
|
||||
}
|
||||
RawExpression::List(list) => {
|
||||
let mut exprs = vec![];
|
||||
|
||||
for expr in list {
|
||||
let expr = evaluate_baseline_expr(expr, registry, scope, source)?;
|
||||
exprs.push(expr);
|
||||
}
|
||||
|
||||
Ok(Value::List(exprs).spanned(expr.span()))
|
||||
}
|
||||
RawExpression::Block(block) => Ok(Spanned::from_item(
|
||||
Value::Block(Block::new(block.clone(), source.clone(), *expr.span())),
|
||||
expr.span(),
|
||||
|
@ -1,11 +1,15 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(async_await)]
|
||||
#![feature(generators)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(bind_by_move_pattern_guards)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(type_ascription)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(option_flattening)]
|
||||
#![feature(specialization)]
|
||||
#![feature(proc_macro_hygiene)]
|
||||
|
||||
#[macro_use]
|
||||
mod prelude;
|
||||
@ -37,4 +41,4 @@ pub use cli::cli;
|
||||
pub use errors::ShellError;
|
||||
pub use object::base::{Primitive, Value};
|
||||
pub use parser::parse::text::Text;
|
||||
pub use parser::registry::{CommandConfig, EvaluatedArgs, NamedType, PositionalType};
|
||||
pub use parser::registry::{EvaluatedArgs, NamedType, PositionalType, Signature};
|
||||
|
@ -6,6 +6,6 @@ crate mod into;
|
||||
crate mod process;
|
||||
crate mod types;
|
||||
|
||||
crate use base::{Primitive, Value};
|
||||
crate use base::{Block, Primitive, Switch, Value};
|
||||
crate use dict::{Dictionary, SpannedDictBuilder};
|
||||
crate use files::dir_entry_dict;
|
||||
|
@ -10,7 +10,7 @@ use chrono::{DateTime, Utc};
|
||||
use chrono_humanize::Humanize;
|
||||
use derive_new::new;
|
||||
use ordered_float::OrderedFloat;
|
||||
use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::path::PathBuf;
|
||||
use std::time::SystemTime;
|
||||
@ -123,42 +123,13 @@ pub struct Operation {
|
||||
crate right: Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new)]
|
||||
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Serialize, Deserialize, new)]
|
||||
pub struct Block {
|
||||
crate expressions: Vec<hir::Expression>,
|
||||
crate source: Text,
|
||||
crate span: Span,
|
||||
}
|
||||
|
||||
impl Serialize for Block {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
|
||||
let list = self
|
||||
.expressions
|
||||
.iter()
|
||||
.map(|e| e.source(&self.source.clone()));
|
||||
|
||||
for item in list {
|
||||
seq.serialize_element(item.as_ref())?;
|
||||
}
|
||||
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize<'de> for Block {
|
||||
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
unimplemented!("deserialize block")
|
||||
}
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn invoke(&self, value: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
|
||||
let scope = Scope::new(value.clone());
|
||||
@ -260,6 +231,7 @@ impl std::convert::TryFrom<&'a Spanned<Value>> for i64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum Switch {
|
||||
Present,
|
||||
Absent,
|
||||
|
@ -1,12 +1,15 @@
|
||||
use crate::commands::from_toml::convert_toml_value_to_nu_value;
|
||||
use crate::commands::to_toml::value_to_toml_value;
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{Dictionary, Value};
|
||||
use crate::prelude::*;
|
||||
use app_dirs::*;
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const APP_INFO: AppInfo = AppInfo {
|
||||
name: "nu",
|
||||
@ -16,7 +19,14 @@ const APP_INFO: AppInfo = AppInfo {
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct Config {
|
||||
#[serde(flatten)]
|
||||
extra: IndexMap<String, Spanned<Value>>,
|
||||
extra: IndexMap<String, Value>,
|
||||
}
|
||||
|
||||
crate fn config_path() -> Result<PathBuf, ShellError> {
|
||||
let location = app_root(AppDataType::UserConfig, &APP_INFO)
|
||||
.map_err(|err| ShellError::string(&format!("Couldn't open config file:\n{}", err)))?;
|
||||
|
||||
Ok(location.join("config.toml"))
|
||||
}
|
||||
|
||||
crate fn write_config(config: &IndexMap<String, Spanned<Value>>) -> Result<(), ShellError> {
|
||||
@ -26,9 +36,9 @@ crate fn write_config(config: &IndexMap<String, Spanned<Value>>) -> Result<(), S
|
||||
let filename = location.join("config.toml");
|
||||
touch(&filename)?;
|
||||
|
||||
let contents = toml::to_string(&Config {
|
||||
extra: config.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
|
||||
})?;
|
||||
let contents = value_to_toml_value(&Value::Object(Dictionary::new(config.clone())));
|
||||
|
||||
let contents = toml::to_string(&contents)?;
|
||||
|
||||
fs::write(&filename, &contents)?;
|
||||
|
||||
@ -50,10 +60,18 @@ crate fn config(span: impl Into<Span>) -> Result<IndexMap<String, Spanned<Value>
|
||||
.map(|v| v.spanned(span))
|
||||
.map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?;
|
||||
|
||||
let parsed: Config = toml::from_str(&contents)
|
||||
let parsed: toml::Value = toml::from_str(&contents)
|
||||
.map_err(|err| ShellError::string(&format!("Couldn't parse config file:\n{}", err)))?;
|
||||
|
||||
Ok(parsed.extra)
|
||||
let value = convert_toml_value_to_nu_value(&parsed, span);
|
||||
|
||||
match value.item {
|
||||
Value::Object(Dictionary { entries }) => Ok(entries),
|
||||
other => Err(ShellError::type_error(
|
||||
"Dictionary",
|
||||
other.type_name().spanned(value.span),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
// A simple implementation of `% touch path` (ignores existing files)
|
||||
|
@ -1,16 +1,9 @@
|
||||
use crate::object::base as value;
|
||||
use crate::parser::hir;
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use serde_derive::Deserialize;
|
||||
use log::trace;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub trait Type: std::fmt::Debug + Send {
|
||||
type Extractor: ExtractType;
|
||||
|
||||
fn name(&self) -> &'static str;
|
||||
}
|
||||
|
||||
pub trait ExtractType: Sized {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError>;
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError>;
|
||||
@ -19,8 +12,120 @@ pub trait ExtractType: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ExtractType for T {
|
||||
default fn extract(_value: &Spanned<Value>) -> Result<T, ShellError> {
|
||||
let name = unsafe { std::intrinsics::type_name::<T>() };
|
||||
Err(ShellError::unimplemented(format!(
|
||||
"<T> ExtractType for {}",
|
||||
name
|
||||
)))
|
||||
}
|
||||
|
||||
default fn check(_value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
Err(ShellError::unimplemented("ExtractType for T"))
|
||||
}
|
||||
|
||||
default fn syntax_type() -> hir::SyntaxType {
|
||||
hir::SyntaxType::Any
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ExtractType> ExtractType for Vec<Spanned<T>> {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError> {
|
||||
let name = unsafe { std::intrinsics::type_name::<T>() };
|
||||
trace!("<Vec> Extracting {:?} for Vec<{}>", value, name);
|
||||
|
||||
match value.item() {
|
||||
Value::List(items) => {
|
||||
let mut out = vec![];
|
||||
|
||||
for item in items {
|
||||
out.push(T::extract(item)?.spanned(item.span));
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
}
|
||||
other => Err(ShellError::type_error(
|
||||
"Vec",
|
||||
other.type_name().spanned(value.span),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
match value.item() {
|
||||
Value::List(_) => Ok(value),
|
||||
other => Err(ShellError::type_error(
|
||||
"Vec",
|
||||
other.type_name().spanned(value.span),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn syntax_type() -> hir::SyntaxType {
|
||||
hir::SyntaxType::List
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ExtractType, U: ExtractType> ExtractType for (T, U) {
|
||||
fn extract(value: &Spanned<Value>) -> Result<(T, U), ShellError> {
|
||||
let t_name = unsafe { std::intrinsics::type_name::<T>() };
|
||||
let u_name = unsafe { std::intrinsics::type_name::<U>() };
|
||||
|
||||
trace!("Extracting {:?} for ({}, {})", value, t_name, u_name);
|
||||
|
||||
match value.item() {
|
||||
Value::List(items) => {
|
||||
if items.len() == 2 {
|
||||
let first = &items[0];
|
||||
let second = &items[1];
|
||||
|
||||
Ok((T::extract(first)?, U::extract(second)?))
|
||||
} else {
|
||||
Err(ShellError::type_error(
|
||||
"two-element-tuple",
|
||||
"not-two".spanned(value.span),
|
||||
))
|
||||
}
|
||||
}
|
||||
other => Err(ShellError::type_error(
|
||||
"two-element-tuple",
|
||||
other.type_name().spanned(value.span),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ExtractType> ExtractType for Option<T> {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Option<T>, ShellError> {
|
||||
let name = unsafe { std::intrinsics::type_name::<T>() };
|
||||
trace!("<Option> Extracting {:?} for Option<{}>", value, name);
|
||||
|
||||
let result = match value.item() {
|
||||
Value::Primitive(Primitive::Nothing) => None,
|
||||
_ => Some(T::extract(value)?),
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
match value.item() {
|
||||
Value::Primitive(Primitive::Nothing) => Ok(value),
|
||||
_ => T::check(value),
|
||||
}
|
||||
}
|
||||
|
||||
fn syntax_type() -> hir::SyntaxType {
|
||||
T::syntax_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ExtractType> ExtractType for Spanned<T> {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Spanned<T>, ShellError> {
|
||||
let name = unsafe { std::intrinsics::type_name::<T>() };
|
||||
trace!("<Spanned> Extracting {:?} for Spanned<{}>", value, name);
|
||||
|
||||
Ok(T::extract(value)?.spanned(value.span))
|
||||
}
|
||||
|
||||
@ -33,25 +138,52 @@ impl<T: ExtractType> ExtractType for Spanned<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
|
||||
pub struct Any;
|
||||
impl ExtractType for Value {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Value, ShellError> {
|
||||
trace!("<Spanned> Extracting {:?} for Value", value);
|
||||
|
||||
impl Type for Any {
|
||||
type Extractor = Spanned<Value>;
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Any"
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for Spanned<Value> {
|
||||
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError> {
|
||||
Ok(value.clone())
|
||||
Ok(value.item().clone())
|
||||
}
|
||||
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn syntax_type() -> hir::SyntaxType {
|
||||
SyntaxType::Any
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for bool {
|
||||
fn syntax_type() -> hir::SyntaxType {
|
||||
hir::SyntaxType::Boolean
|
||||
}
|
||||
|
||||
fn extract(value: &'a Spanned<Value>) -> Result<bool, ShellError> {
|
||||
trace!("Extracting {:?} for bool", value);
|
||||
|
||||
match &value {
|
||||
Spanned {
|
||||
item: Value::Primitive(Primitive::Boolean(b)),
|
||||
..
|
||||
} => Ok(*b),
|
||||
Spanned {
|
||||
item: Value::Primitive(Primitive::Nothing),
|
||||
..
|
||||
} => Ok(false),
|
||||
other => Err(ShellError::type_error("Boolean", other.spanned_type_name())),
|
||||
}
|
||||
}
|
||||
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
match &value {
|
||||
value @ Spanned {
|
||||
item: Value::Primitive(Primitive::Boolean(_)),
|
||||
..
|
||||
} => Ok(value),
|
||||
other => Err(ShellError::type_error("Boolean", other.spanned_type_name())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for std::path::PathBuf {
|
||||
@ -60,6 +192,8 @@ impl ExtractType for std::path::PathBuf {
|
||||
}
|
||||
|
||||
fn extract(value: &'a Spanned<Value>) -> Result<std::path::PathBuf, ShellError> {
|
||||
trace!("Extracting {:?} for PathBuf", value);
|
||||
|
||||
match &value {
|
||||
Spanned {
|
||||
item: Value::Primitive(Primitive::String(p)),
|
||||
@ -80,19 +214,10 @@ impl ExtractType for std::path::PathBuf {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
|
||||
pub struct Integer;
|
||||
|
||||
impl Type for Integer {
|
||||
type Extractor = i64;
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Integer"
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for i64 {
|
||||
fn extract(value: &Spanned<Value>) -> Result<i64, ShellError> {
|
||||
trace!("Extracting {:?} for i64", value);
|
||||
|
||||
match value {
|
||||
&Spanned {
|
||||
item: Value::Primitive(Primitive::Int(int)),
|
||||
@ -113,19 +238,10 @@ impl ExtractType for i64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
|
||||
pub struct NuString;
|
||||
|
||||
impl Type for NuString {
|
||||
type Extractor = String;
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Integer"
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for String {
|
||||
fn extract(value: &Spanned<Value>) -> Result<String, ShellError> {
|
||||
trace!("Extracting {:?} for String", value);
|
||||
|
||||
match value {
|
||||
Spanned {
|
||||
item: Value::Primitive(Primitive::String(string)),
|
||||
@ -146,19 +262,10 @@ impl ExtractType for String {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
|
||||
pub struct Block;
|
||||
|
||||
impl Type for Block {
|
||||
type Extractor = value::Block;
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Block"
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtractType for value::Block {
|
||||
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
|
||||
trace!("Extracting {:?} for Block", value);
|
||||
|
||||
match value {
|
||||
v @ Spanned {
|
||||
item: Value::Block(_),
|
||||
|
@ -1,3 +1,4 @@
|
||||
crate mod deserializer;
|
||||
crate mod hir;
|
||||
crate mod parse;
|
||||
crate mod parse_command;
|
||||
@ -5,6 +6,7 @@ crate mod registry;
|
||||
|
||||
use crate::errors::ShellError;
|
||||
|
||||
crate use deserializer::ConfigDeserializer;
|
||||
crate use hir::baseline_parse_tokens::baseline_parse_tokens;
|
||||
crate use parse::call_node::CallNode;
|
||||
crate use parse::files::Files;
|
||||
|
307
src/parser/deserializer.rs
Normal file
307
src/parser/deserializer.rs
Normal file
@ -0,0 +1,307 @@
|
||||
use crate::commands::command::EvaluatedCommandArgs;
|
||||
use crate::prelude::*;
|
||||
use log::trace;
|
||||
use serde::{de, forward_to_deserialize_any};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeserializerItem<'de> {
|
||||
key: String,
|
||||
struct_field: &'de str,
|
||||
val: Spanned<Value>,
|
||||
}
|
||||
|
||||
pub struct ConfigDeserializer<'de> {
|
||||
args: EvaluatedCommandArgs,
|
||||
stack: Vec<DeserializerItem<'de>>,
|
||||
saw_root: bool,
|
||||
position: usize,
|
||||
}
|
||||
|
||||
impl ConfigDeserializer<'de> {
|
||||
pub fn from_call_node(args: EvaluatedCommandArgs) -> ConfigDeserializer<'de> {
|
||||
ConfigDeserializer {
|
||||
args,
|
||||
stack: vec![],
|
||||
saw_root: false,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, name: &'static str) -> Result<(), ShellError> {
|
||||
let value: Option<Spanned<Value>> = if name == "rest" {
|
||||
let positional = self.args.slice_from(self.position);
|
||||
self.position += positional.len();
|
||||
Some(Value::List(positional).spanned_unknown()) // TODO: correct span
|
||||
} else {
|
||||
if self.args.has(name) {
|
||||
self.args.get(name).map(|x| x.clone())
|
||||
} else {
|
||||
let position = self.position;
|
||||
self.position += 1;
|
||||
self.args.nth(position).map(|x| x.clone())
|
||||
}
|
||||
};
|
||||
|
||||
trace!("pushing {:?}", value);
|
||||
|
||||
self.stack.push(DeserializerItem {
|
||||
key: name.to_string(),
|
||||
struct_field: name,
|
||||
val: value.unwrap_or_else(|| Value::nothing().spanned(self.args.call_info.name_span)),
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> DeserializerItem {
|
||||
let value = self.stack.pop();
|
||||
trace!("popping value :: {:?}", value);
|
||||
value.expect("Can't pop an empty stack")
|
||||
}
|
||||
}
|
||||
|
||||
use de::Visitor;
|
||||
|
||||
impl<'de, 'a> de::Deserializer<'de> for &'a mut ConfigDeserializer<'de> {
|
||||
type Error = ShellError;
|
||||
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
let value = self.pop();
|
||||
let name = unsafe { std::intrinsics::type_name::<V::Value>() };
|
||||
trace!("<Deserialize any> Extracting {:?}", name);
|
||||
|
||||
V::Value::extract(&value.val)
|
||||
}
|
||||
|
||||
forward_to_deserialize_any! { bool option seq }
|
||||
|
||||
fn deserialize_i8<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_i8")
|
||||
}
|
||||
fn deserialize_i16<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_i16")
|
||||
}
|
||||
fn deserialize_i32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_i32")
|
||||
}
|
||||
fn deserialize_i64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_i64")
|
||||
}
|
||||
fn deserialize_u8<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_u8")
|
||||
}
|
||||
fn deserialize_u16<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_u16")
|
||||
}
|
||||
fn deserialize_u32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_u32")
|
||||
}
|
||||
fn deserialize_u64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_u64")
|
||||
}
|
||||
fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_f32")
|
||||
}
|
||||
fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_f64")
|
||||
}
|
||||
fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_char")
|
||||
}
|
||||
fn deserialize_str<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_str")
|
||||
}
|
||||
fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_string")
|
||||
}
|
||||
fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_bytes")
|
||||
}
|
||||
fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_byte_buf")
|
||||
}
|
||||
|
||||
fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_unit")
|
||||
}
|
||||
fn deserialize_unit_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_unit_struct")
|
||||
}
|
||||
fn deserialize_newtype_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_newtype_struct")
|
||||
}
|
||||
|
||||
fn deserialize_tuple<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_tuple")
|
||||
}
|
||||
fn deserialize_tuple_struct<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_tuple_struct")
|
||||
}
|
||||
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_map")
|
||||
}
|
||||
fn deserialize_struct<V>(
|
||||
mut self,
|
||||
name: &'static str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
trace!(
|
||||
"deserializing struct {:?} {:?} (stack={:?})",
|
||||
name,
|
||||
fields,
|
||||
self.stack
|
||||
);
|
||||
|
||||
if self.saw_root {
|
||||
let value = self.pop();
|
||||
let name = unsafe { std::intrinsics::type_name::<V::Value>() };
|
||||
trace!("Extracting {:?} for {:?}", value.val, name);
|
||||
V::Value::extract(&value.val)
|
||||
} else {
|
||||
self.saw_root = true;
|
||||
visitor.visit_seq(StructDeserializer::new(&mut self, fields))
|
||||
}
|
||||
}
|
||||
fn deserialize_enum<V>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variants: &'static [&'static str],
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_enum")
|
||||
}
|
||||
fn deserialize_identifier<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_identifier")
|
||||
}
|
||||
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: Visitor<'de>,
|
||||
{
|
||||
unimplemented!("deserialize_ignored_any")
|
||||
}
|
||||
}
|
||||
|
||||
struct StructDeserializer<'a, 'de: 'a> {
|
||||
de: &'a mut ConfigDeserializer<'de>,
|
||||
fields: &'static [&'static str],
|
||||
}
|
||||
|
||||
impl<'a, 'de: 'a> StructDeserializer<'a, 'de> {
|
||||
fn new(de: &'a mut ConfigDeserializer<'de>, fields: &'static [&'static str]) -> Self {
|
||||
StructDeserializer {
|
||||
de: de,
|
||||
fields: fields,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'de: 'a> de::SeqAccess<'de> for StructDeserializer<'a, 'de> {
|
||||
type Error = ShellError;
|
||||
|
||||
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
|
||||
where
|
||||
T: de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.fields.len() == 0 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
trace!("Processing {}", self.fields[0]);
|
||||
|
||||
self.de.push(self.fields[0])?;
|
||||
self.fields = &self.fields[1..];
|
||||
seed.deserialize(&mut *self.de).map(Some)
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
return Some(self.fields.len());
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ use crate::parser::{registry, Span, Spanned, Unit};
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
crate use baseline_parse::{baseline_parse_single_token, baseline_parse_token_as_string};
|
||||
@ -76,6 +76,7 @@ pub enum RawExpression {
|
||||
Variable(Variable),
|
||||
Binary(Box<Binary>),
|
||||
Block(Vec<Expression>),
|
||||
List(Vec<Expression>),
|
||||
Path(Box<Path>),
|
||||
|
||||
#[allow(unused)]
|
||||
@ -101,6 +102,7 @@ impl RawExpression {
|
||||
RawExpression::Literal(literal) => literal.type_name(),
|
||||
RawExpression::Synthetic(synthetic) => synthetic.type_name(),
|
||||
RawExpression::Variable(..) => "variable",
|
||||
RawExpression::List(..) => "list",
|
||||
RawExpression::Binary(..) => "binary",
|
||||
RawExpression::Block(..) => "block",
|
||||
RawExpression::Path(..) => "path",
|
||||
@ -170,6 +172,15 @@ impl ToDebug for Expression {
|
||||
|
||||
write!(f, "}}")
|
||||
}
|
||||
RawExpression::List(exprs) => {
|
||||
write!(f, "[ ")?;
|
||||
|
||||
for expr in exprs {
|
||||
write!(f, "{} ", expr.debug(source))?;
|
||||
}
|
||||
|
||||
write!(f, "]")
|
||||
}
|
||||
RawExpression::Path(p) => write!(f, "{}", p.debug(source)),
|
||||
RawExpression::Boolean(true) => write!(f, "$yes"),
|
||||
RawExpression::Boolean(false) => write!(f, "$no"),
|
||||
|
@ -8,7 +8,7 @@ use crate::parser::{
|
||||
use crate::{SpannedItem, Text};
|
||||
use derive_new::new;
|
||||
use log::trace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub fn baseline_parse_tokens(
|
||||
token_nodes: &mut TokensIterator<'_>,
|
||||
@ -33,6 +33,7 @@ pub fn baseline_parse_tokens(
|
||||
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||
pub enum SyntaxType {
|
||||
Any,
|
||||
List,
|
||||
Literal,
|
||||
Variable,
|
||||
Path,
|
||||
@ -210,7 +211,14 @@ pub fn baseline_parse_delimited(
|
||||
Ok(Spanned::from_item(expr, token.span()))
|
||||
}
|
||||
Delimiter::Paren => unimplemented!(),
|
||||
Delimiter::Square => unimplemented!(),
|
||||
Delimiter::Square => {
|
||||
let children = token.children();
|
||||
let exprs =
|
||||
baseline_parse_tokens(&mut TokensIterator::new(children), registry, source)?;
|
||||
|
||||
let expr = hir::RawExpression::List(exprs);
|
||||
Ok(expr.spanned(token.span()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use crate::parser::{hir::Expression, Operator, Spanned};
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(
|
||||
|
@ -4,7 +4,7 @@ use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use indexmap::IndexMap;
|
||||
use log::trace;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||
|
@ -2,7 +2,7 @@ use crate::parser::{hir::Expression, Spanned};
|
||||
use crate::prelude::*;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::parser::Span;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
||||
pub enum FlagKind {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::prelude::*;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -2,8 +2,8 @@ use crate::prelude::*;
|
||||
use crate::Text;
|
||||
use derive_new::new;
|
||||
use getset::Getters;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use serde_derive::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use crate::object::base::Value;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
||||
pub enum Unit {
|
||||
@ -46,7 +46,7 @@ impl FromStr for Unit {
|
||||
type Err = ();
|
||||
fn from_str(input: &str) -> Result<Self, <Self as std::str::FromStr>::Err> {
|
||||
match input {
|
||||
"B" | "b" => Ok(Unit::B),
|
||||
"B" | "b" => Ok(Unit::B),
|
||||
"KB" | "kb" | "Kb" | "K" | "k" => Ok(Unit::KB),
|
||||
"MB" | "mb" | "Mb" => Ok(Unit::MB),
|
||||
"GB" | "gb" | "Gb" => Ok(Unit::GB),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::errors::{ArgumentError, ShellError};
|
||||
use crate::parser::registry::{CommandConfig, CommandRegistry, NamedType, PositionalType};
|
||||
use crate::parser::registry::{Signature, CommandRegistry, NamedType, PositionalType};
|
||||
use crate::parser::{baseline_parse_tokens, CallNode, Span, Spanned};
|
||||
use crate::parser::{
|
||||
hir::{self, NamedArguments},
|
||||
@ -9,7 +9,7 @@ use crate::Text;
|
||||
use log::trace;
|
||||
|
||||
pub fn parse_command(
|
||||
config: &CommandConfig,
|
||||
config: &Signature,
|
||||
registry: &CommandRegistry,
|
||||
call: &Spanned<CallNode>,
|
||||
source: &Text,
|
||||
@ -62,7 +62,7 @@ fn parse_command_head(head: &TokenNode) -> Result<hir::Expression, ShellError> {
|
||||
}
|
||||
|
||||
fn parse_command_tail(
|
||||
config: &CommandConfig,
|
||||
config: &Signature,
|
||||
registry: &CommandRegistry,
|
||||
tail: Option<Vec<TokenNode>>,
|
||||
source: &Text,
|
||||
@ -197,7 +197,7 @@ fn extract_switch(name: &str, tokens: &mut hir::TokensIterator<'_>, source: &Tex
|
||||
}
|
||||
|
||||
fn extract_mandatory(
|
||||
config: &CommandConfig,
|
||||
config: &Signature,
|
||||
name: &str,
|
||||
tokens: &mut hir::TokensIterator<'a>,
|
||||
source: &Text,
|
||||
|
@ -69,52 +69,76 @@ impl PositionalType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct CommandConfig {
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, new)]
|
||||
pub struct Signature {
|
||||
pub name: String,
|
||||
#[new(default)]
|
||||
pub positional: Vec<PositionalType>,
|
||||
#[new(value = "false")]
|
||||
pub rest_positional: bool,
|
||||
#[new(default)]
|
||||
pub named: IndexMap<String, NamedType>,
|
||||
#[new(value = "false")]
|
||||
pub is_filter: bool,
|
||||
pub is_sink: bool,
|
||||
}
|
||||
|
||||
impl CommandConfig {
|
||||
pub fn new(name: impl Into<String>) -> CommandConfig {
|
||||
CommandConfig {
|
||||
name: name.into(),
|
||||
positional: vec![],
|
||||
rest_positional: false,
|
||||
named: IndexMap::default(),
|
||||
is_filter: false,
|
||||
is_sink: false,
|
||||
}
|
||||
impl Signature {
|
||||
pub fn build(name: impl Into<String>) -> Signature {
|
||||
Signature::new(name.into())
|
||||
}
|
||||
|
||||
pub fn required(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> CommandConfig {
|
||||
pub fn required(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature {
|
||||
self.positional
|
||||
.push(PositionalType::Mandatory(name.into(), ty.into()));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn optional(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> CommandConfig {
|
||||
pub fn optional(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature {
|
||||
self.positional
|
||||
.push(PositionalType::Optional(name.into(), ty.into()));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn named(mut self, name: impl Into<String>, ty: impl Into<NamedType>) -> CommandConfig {
|
||||
self.named.insert(name.into(), ty.into());
|
||||
pub fn named(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature {
|
||||
self.named
|
||||
.insert(name.into(), NamedType::Optional(ty.into()));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sink(mut self) -> CommandConfig {
|
||||
pub fn required_named(
|
||||
mut self,
|
||||
name: impl Into<String>,
|
||||
ty: impl Into<SyntaxType>,
|
||||
) -> Signature {
|
||||
self.named
|
||||
.insert(name.into(), NamedType::Mandatory(ty.into()));
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn switch(mut self, name: impl Into<String>) -> Signature {
|
||||
self.named.insert(name.into(), NamedType::Switch);
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn sink(mut self) -> Signature {
|
||||
self.is_sink = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn filter(mut self) -> Signature {
|
||||
self.is_filter = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn rest(mut self) -> Signature {
|
||||
self.rest_positional = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, new, Serialize, Deserialize)]
|
||||
@ -245,7 +269,7 @@ impl Iterator for PositionalIter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl CommandConfig {
|
||||
impl Signature {
|
||||
crate fn parse_args(
|
||||
&self,
|
||||
call: &Spanned<CallNode>,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::{CallInfo, CommandConfig, ReturnValue, ShellError, Spanned, Value};
|
||||
use crate::{CallInfo, Signature, ReturnValue, ShellError, Spanned, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
|
||||
pub trait Plugin {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError>;
|
||||
fn config(&mut self) -> Result<Signature, ShellError>;
|
||||
#[allow(unused)]
|
||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> {
|
||||
Err(ShellError::string(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||
serve_plugin, CallInfo, Signature, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||
ReturnValue, ShellError, Spanned, Value,
|
||||
};
|
||||
|
||||
@ -40,8 +40,8 @@ impl Add {
|
||||
}
|
||||
|
||||
impl Plugin for Add {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
Ok(CommandConfig {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
Ok(Signature {
|
||||
name: "add".to_string(),
|
||||
positional: vec![
|
||||
PositionalType::mandatory_any("Field"),
|
||||
|
@ -2,7 +2,7 @@
|
||||
use crossterm::{cursor, terminal, Attribute, RawScreen};
|
||||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, ShellError, SpanSource, Spanned,
|
||||
serve_plugin, CallInfo, Signature, NamedType, Plugin, ShellError, SpanSource, Spanned,
|
||||
Value,
|
||||
};
|
||||
use pretty_hex::*;
|
||||
@ -16,10 +16,10 @@ impl BinaryView {
|
||||
}
|
||||
|
||||
impl Plugin for BinaryView {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
let mut named = IndexMap::new();
|
||||
named.insert("lores".to_string(), NamedType::Switch);
|
||||
Ok(CommandConfig {
|
||||
Ok(Signature {
|
||||
name: "binaryview".to_string(),
|
||||
positional: vec![],
|
||||
is_filter: false,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||
serve_plugin, CallInfo, Signature, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||
ReturnValue, ShellError, Spanned, Value,
|
||||
};
|
||||
|
||||
@ -40,8 +40,8 @@ impl Edit {
|
||||
}
|
||||
|
||||
impl Plugin for Edit {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
Ok(CommandConfig {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
Ok(Signature {
|
||||
name: "edit".to_string(),
|
||||
positional: vec![
|
||||
PositionalType::mandatory_any("Field"),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive,
|
||||
serve_plugin, CallInfo, Signature, NamedType, Plugin, PositionalType, Primitive,
|
||||
ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value,
|
||||
};
|
||||
|
||||
@ -84,13 +84,13 @@ impl Inc {
|
||||
}
|
||||
|
||||
impl Plugin for Inc {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
let mut named = IndexMap::new();
|
||||
named.insert("major".to_string(), NamedType::Switch);
|
||||
named.insert("minor".to_string(), NamedType::Switch);
|
||||
named.insert("patch".to_string(), NamedType::Switch);
|
||||
|
||||
Ok(CommandConfig {
|
||||
Ok(Signature {
|
||||
name: "inc".to_string(),
|
||||
positional: vec![PositionalType::optional_any("Field")],
|
||||
is_filter: true,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue,
|
||||
serve_plugin, CallInfo, Signature, Plugin, Primitive, ReturnSuccess, ReturnValue,
|
||||
ShellError, Spanned, Value,
|
||||
};
|
||||
|
||||
@ -14,8 +14,8 @@ impl NewSkip {
|
||||
}
|
||||
|
||||
impl Plugin for NewSkip {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
Ok(CommandConfig {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
Ok(Signature {
|
||||
name: "skip".to_string(),
|
||||
positional: vec![],
|
||||
is_filter: true,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use derive_new::new;
|
||||
use indexmap::IndexMap;
|
||||
use nu::{serve_plugin, CallInfo, CommandConfig, Plugin, ShellError, Spanned, Value};
|
||||
use nu::{serve_plugin, CallInfo, Signature, Plugin, ShellError, Spanned, Value};
|
||||
use ptree::item::StringItem;
|
||||
use ptree::output::print_tree_with;
|
||||
use ptree::print_config::PrintConfig;
|
||||
@ -80,8 +80,8 @@ impl TreeView {
|
||||
struct TreeViewer;
|
||||
|
||||
impl Plugin for TreeViewer {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||
Ok(CommandConfig {
|
||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||
Ok(Signature {
|
||||
name: "tree".to_string(),
|
||||
positional: vec![],
|
||||
is_filter: false,
|
||||
|
@ -34,20 +34,23 @@ macro_rules! trace_stream {
|
||||
|
||||
crate use crate::cli::MaybeOwned;
|
||||
crate use crate::commands::command::{
|
||||
Command, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, Sink, SinkCommandArgs,
|
||||
CommandAction, CommandArgs, ReturnSuccess, ReturnValue, RunnableContext,
|
||||
};
|
||||
crate use crate::context::{CommandRegistry, Context};
|
||||
crate use crate::env::host::handle_unexpected;
|
||||
crate use crate::env::{Environment, Host};
|
||||
crate use crate::errors::ShellError;
|
||||
crate use crate::object::base as value;
|
||||
crate use crate::object::types::ExtractType;
|
||||
crate use crate::object::{Primitive, Value};
|
||||
crate use crate::parser::{Span, Spanned, SpannedItem};
|
||||
crate use crate::parser::registry::Signature;
|
||||
crate use crate::parser::{hir::SyntaxType, Span, Spanned, SpannedItem};
|
||||
crate use crate::stream::{InputStream, OutputStream};
|
||||
crate use crate::traits::{HasSpan, ToDebug};
|
||||
crate use crate::Text;
|
||||
crate use futures::stream::BoxStream;
|
||||
crate use futures::{FutureExt, Stream, StreamExt};
|
||||
crate use serde::{Deserialize, Serialize};
|
||||
crate use std::collections::VecDeque;
|
||||
crate use std::future::Future;
|
||||
crate use std::sync::{Arc, Mutex};
|
||||
|
@ -46,12 +46,17 @@ pub struct OutputStream {
|
||||
}
|
||||
|
||||
impl OutputStream {
|
||||
#[allow(unused)]
|
||||
pub fn empty() -> OutputStream {
|
||||
let v: VecDeque<ReturnValue> = VecDeque::new();
|
||||
v.into()
|
||||
}
|
||||
|
||||
pub fn one(item: impl Into<ReturnValue>) -> OutputStream {
|
||||
let v: VecDeque<ReturnValue> = VecDeque::new();
|
||||
v.push_back(item.into());
|
||||
v.into()
|
||||
}
|
||||
|
||||
pub fn from_input(input: impl Stream<Item = Spanned<Value>> + Send + 'static) -> OutputStream {
|
||||
OutputStream {
|
||||
values: input.map(ReturnSuccess::value).boxed(),
|
||||
|
22
src/utils.rs
22
src/utils.rs
@ -19,13 +19,18 @@ impl AbsolutePath {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<&str> for AbsolutePath {
|
||||
impl Div<&str> for &AbsolutePath {
|
||||
type Output = AbsolutePath;
|
||||
|
||||
fn div(self, rhs: &str) -> Self::Output {
|
||||
AbsolutePath {
|
||||
inner: self.inner.join(rhs),
|
||||
let parts = rhs.split("/");
|
||||
let mut result = self.inner.clone();
|
||||
|
||||
for part in parts {
|
||||
result = result.join(part);
|
||||
}
|
||||
|
||||
AbsolutePath::new(result)
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,12 +56,17 @@ impl RelativePath {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: AsRef<str>> Div<T> for RelativePath {
|
||||
impl<T: AsRef<str>> Div<T> for &RelativePath {
|
||||
type Output = RelativePath;
|
||||
|
||||
fn div(self, rhs: T) -> Self::Output {
|
||||
RelativePath {
|
||||
inner: self.inner.join(rhs.as_ref()),
|
||||
let parts = rhs.as_ref().split("/");
|
||||
let mut result = self.inner.clone();
|
||||
|
||||
for part in parts {
|
||||
result = result.join(part);
|
||||
}
|
||||
|
||||
RelativePath::new(result)
|
||||
}
|
||||
}
|
||||
|
@ -83,27 +83,32 @@ fn open_error_if_file_not_found() {
|
||||
|
||||
#[test]
|
||||
fn save_can_write_out_csv() -> Result<(), std::io::Error> {
|
||||
let (playground, tmp, dir) = h::setup_playground_for("save_test")?;
|
||||
let (playground, tmp, _dir) = h::setup_playground_for("save_test")?;
|
||||
|
||||
let tmp = AbsolutePath::new(tmp);
|
||||
let expected_file = tmp.as_ref().join("cargo_sample.csv");
|
||||
|
||||
let expected_file = tmp / "cargo_sample.csv";
|
||||
let root = &AbsolutePath::new(std::env::current_dir()?);
|
||||
|
||||
let root = AbsolutePath::new(std::env::current_dir()?);
|
||||
|
||||
let path = root / "tests" / "fixtures" / "formats" / "cargo_sample.toml";
|
||||
let path = root / "tests/fixtures/formats/cargo_sample.toml";
|
||||
|
||||
let command = format!(
|
||||
"open {} | inc package.version --minor | get package | save {}/cargo_sample.csv",
|
||||
"open {} | inc package.version --minor | get package | save {}",
|
||||
path.as_ref().display(),
|
||||
dir
|
||||
"cargo_sample.csv"
|
||||
);
|
||||
|
||||
nu!(_output, playground.path().display(), command);
|
||||
for item in std::fs::read_dir(tmp.as_ref()) {
|
||||
println!("item :: {:?}", item);
|
||||
}
|
||||
|
||||
nu!(_output, tmp.as_ref().display(), command);
|
||||
|
||||
let actual = h::file_contents(&expected_file);
|
||||
assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0"));
|
||||
|
||||
drop(playground);
|
||||
drop(tmp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -113,8 +118,7 @@ fn rm_can_remove_a_file() -> Result<(), std::io::Error> {
|
||||
|
||||
let (_playground, tmp, _) = h::setup_playground_for("remove_file")?;
|
||||
|
||||
let file = AbsolutePath::new(&tmp) / "rm_test.txt";
|
||||
// let file = tmp.path().join("rm_test.txt");
|
||||
let file = &AbsolutePath::new(&tmp) / "rm_test.txt";
|
||||
|
||||
h::create_file_at(&file)?;
|
||||
|
||||
|
@ -82,6 +82,8 @@ macro_rules! nu_error {
|
||||
}
|
||||
|
||||
pub fn setup_playground_for(topic: &str) -> Result<(TempDir, TempDir, String), std::io::Error> {
|
||||
let _ = pretty_env_logger::try_init();
|
||||
|
||||
let home = TempDir::new("nuplayground")?;
|
||||
let child = TempDir::new_in(home.path(), topic)?;
|
||||
let relative = child
|
||||
@ -105,7 +107,10 @@ pub fn setup_playground_for(topic: &str) -> Result<(TempDir, TempDir, String), s
|
||||
}
|
||||
|
||||
pub fn file_contents(full_path: impl AsRef<Path>) -> String {
|
||||
let mut file = std::fs::File::open(full_path).expect("can not open file");
|
||||
let full_path = full_path.as_ref();
|
||||
|
||||
let mut file = std::fs::File::open(full_path)
|
||||
.expect(&format!("can not open file {}", &full_path.display()));
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)
|
||||
.expect("can not read file");
|
||||
|
Loading…
Reference in New Issue
Block a user