Restructuring

This commit is contained in:
Yehuda Katz 2019-08-02 12:15:07 -07:00
parent 73deeb69db
commit fc173c46d8
54 changed files with 1498 additions and 879 deletions

171
Cargo.lock generated
View File

@ -9,7 +9,7 @@ dependencies = [
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "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 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)", "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]] [[package]]
@ -77,6 +77,16 @@ dependencies = [
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "atty" name = "atty"
version = "0.2.11" version = "0.2.11"
@ -570,7 +580,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"quote 0.6.12 (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]] [[package]]
@ -609,7 +619,7 @@ dependencies = [
"ident_case 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
@ -622,7 +632,7 @@ dependencies = [
"proc-macro2 0.4.30 (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)", "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)", "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]] [[package]]
@ -632,7 +642,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"darling_core 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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]] [[package]]
@ -642,7 +652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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]] [[package]]
@ -661,7 +671,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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]] [[package]]
@ -673,7 +683,7 @@ dependencies = [
"derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
@ -684,7 +694,7 @@ dependencies = [
"darling 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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]] [[package]]
@ -697,7 +707,7 @@ dependencies = [
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "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 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)", "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]] [[package]]
@ -844,7 +854,7 @@ dependencies = [
"proc-macro2 0.4.30 (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)", "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)", "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]] [[package]]
@ -898,7 +908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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)", "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" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "futures-channel-preview" name = "futures-async-stream"
version = "0.3.0-alpha.16" version = "0.1.0-alpha.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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]] [[package]]
name = "futures-core-preview" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -984,56 +1015,51 @@ dependencies = [
[[package]] [[package]]
name = "futures-executor-preview" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"futures-channel-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.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)",
"futures-util-preview 0.3.0-alpha.16 (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)", "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]] [[package]]
name = "futures-io-preview" 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" 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]] [[package]]
name = "futures-preview" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"futures-channel-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.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)",
"futures-executor-preview 0.3.0-alpha.16 (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.16 (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.16 (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.16 (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]] [[package]]
name = "futures-sink-preview" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ 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.17 (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)",
] ]
[[package]] [[package]]
name = "futures-util-preview" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", "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-channel-preview 0.3.0-alpha.17 (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)",
"futures-io-preview 0.3.0-alpha.16 (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.16 (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)", "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)", "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)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1042,11 +1068,11 @@ dependencies = [
[[package]] [[package]]
name = "futures_codec" name = "futures_codec"
version = "0.2.2" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
@ -1065,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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]] [[package]]
@ -1445,7 +1471,7 @@ dependencies = [
"quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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)", "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-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)", "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-async-stream 0.1.0-alpha.1 (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-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)",
"futures_codec 0.2.2 (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)", "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)", "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)", "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 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-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_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_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_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)", "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 = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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]] [[package]]
@ -2000,6 +2027,16 @@ dependencies = [
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
name = "pin-utils" name = "pin-utils"
version = "0.1.0-alpha.4" version = "0.1.0-alpha.4"
@ -2636,7 +2673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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]] [[package]]
@ -2645,7 +2682,7 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "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]] [[package]]
@ -2781,7 +2818,7 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "0.15.37" version = "0.15.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", "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 = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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)", "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 = [ dependencies = [
"darling 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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]] [[package]]
@ -3287,7 +3324,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "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)", "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)", "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)", "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 = [ dependencies = [
"proc-macro2 0.4.30 (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)", "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-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)", "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 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 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 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 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 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" "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 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 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 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-async-stream 0.1.0-alpha.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c4aecac975d38ff13b935de313e12fded407231b0d563e7493fac40463272a2f"
"checksum futures-core-preview 0.3.0-alpha.16 (registry+https://github.com/rust-lang/crates.io-index)" = "719770f328642b657b849856bb5a607db9538dd5bb3000122e5ead55d0a58c36" "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-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-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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cca0bf7a1f39c9d32b797b0def93d5932aa71796236aad6b549bac6f7df159a3" "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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfeac5f016a4b5835bb93eb7961f50a64f0e001207562703d9ddf4109d7b263" "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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "49dcfdacd6b5974ca0b9b78bc38ffd1071da0206179735c3df82e279f5b784e4" "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.16 (registry+https://github.com/rust-lang/crates.io-index)" = "f7a0451b9c5047c2b9ab93425ffd0793165511e93c04b977cd45fbd41c6e34b2" "checksum futures-util-preview 0.3.0-alpha.17 (registry+https://github.com/rust-lang/crates.io-index)" = "af8198c48b222f02326940ce2b3aa9e6e91a32886eeaad7ca3b8e4c70daa3f4e"
"checksum futures_codec 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b60f48aa03e365df015d2fbf0b79f17b440350c268a5e20305da17b394adcc1e" "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 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 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" "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_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_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 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 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 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" "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.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 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 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 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 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" "checksum sys-info 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "76d6cf7b349b6a6daaf7a3797227e2f4108c8dd398e0aca7e29b9fb239948541"

View File

@ -28,18 +28,19 @@ chrono-humanize = "0.0.11"
byte-unit = "2.1.0" byte-unit = "2.1.0"
ordered-float = {version = "1.0.2", features = ["serde"]} ordered-float = {version = "1.0.2", features = ["serde"]}
prettyprint = "0.7.0" prettyprint = "0.7.0"
futures-preview = { version = "=0.3.0-alpha.16", features = ["compat", "io-compat"] } futures-preview = { version = "=0.3.0-alpha.17", features = ["compat", "io-compat"] }
futures-sink-preview = "=0.3.0-alpha.16" futures-sink-preview = "=0.3.0-alpha.17"
futures_codec = "0.2.2" futures-async-stream = "0.1.0-alpha.1"
async-trait = ""
futures_codec = "0.2.5"
term = "0.5.2" term = "0.5.2"
bytes = "0.4.12" bytes = "0.4.12"
log = "0.4.7" log = "0.4.7"
pretty_env_logger = "0.3.0" pretty_env_logger = "0.3.0"
serde = "1.0.94" serde = { version = "1.0.94", features = ["derive"] }
serde_json = "1.0.40" serde_json = "1.0.40"
serde-hjson = "0.9.0" serde-hjson = "0.9.0"
serde_yaml = "0.8" serde_yaml = "0.8"
serde_derive = "1.0.94"
serde_bytes = "0.11.1" serde_bytes = "0.11.1"
getset = "0.0.7" getset = "0.0.7"
logos = "0.10.0-rc2" logos = "0.10.0-rc2"

View File

@ -1,18 +1,17 @@
use crate::commands::autoview; use crate::commands::autoview;
use crate::commands::classified::SinkCommand;
use crate::commands::classified::{ use crate::commands::classified::{
ClassifiedCommand, ClassifiedInputStream, ClassifiedPipeline, ExternalCommand, InternalCommand, ClassifiedCommand, ClassifiedInputStream, ClassifiedPipeline, ExternalCommand, InternalCommand,
StreamNext, StreamNext,
}; };
use crate::commands::command::sink;
use crate::commands::plugin::JsonRpc; 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; use crate::context::Context;
crate use crate::errors::ShellError; crate use crate::errors::ShellError;
use crate::git::current_branch; use crate::git::current_branch;
use crate::object::Value; use crate::object::Value;
use crate::parser::parse::span::Spanned; 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::parser::{hir, Pipeline, PipelineElement, TokenNode};
use crate::prelude::*; use crate::prelude::*;
@ -61,8 +60,7 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel
let mut input = String::new(); let mut input = String::new();
match reader.read_line(&mut input) { match reader.read_line(&mut input) {
Ok(_) => { Ok(_) => {
let response = let response = serde_json::from_str::<JsonRpc<Result<Signature, ShellError>>>(&input);
serde_json::from_str::<JsonRpc<Result<CommandConfig, ShellError>>>(&input);
match response { match response {
Ok(jrpc) => match jrpc.params { Ok(jrpc) => match jrpc.params {
Ok(params) => { Ok(params) => {
@ -70,15 +68,10 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel
if params.is_filter { if params.is_filter {
let fname = fname.to_string(); let fname = fname.to_string();
let name = params.name.clone(); let name = params.name.clone();
context.add_commands(vec![Arc::new(PluginCommand::new( context.add_commands(vec![static_command(PluginCommand::new(
name, fname, params, name, fname, params,
))]); ))]);
Ok(()) 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 { } else {
Ok(()) Ok(())
} }
@ -158,10 +151,8 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
command("ps", Box::new(ps::ps)), command("ps", Box::new(ps::ps)),
command("ls", Box::new(ls::ls)), command("ls", Box::new(ls::ls)),
command("sysinfo", Box::new(sysinfo::sysinfo)), command("sysinfo", Box::new(sysinfo::sysinfo)),
command("cd", Box::new(cd::cd)),
command("size", Box::new(size::size)), command("size", Box::new(size::size)),
command("from-yaml", Box::new(from_yaml::from_yaml)), command("from-yaml", Box::new(from_yaml::from_yaml)),
command("get", Box::new(get::get)),
command("exit", Box::new(exit::exit)), command("exit", Box::new(exit::exit)),
command("lines", Box::new(lines::lines)), command("lines", Box::new(lines::lines)),
command("split-column", Box::new(split_column::split_column)), 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-toml", Box::new(to_toml::to_toml)),
command("to-yaml", Box::new(to_yaml::to_yaml)), command("to-yaml", Box::new(to_yaml::to_yaml)),
command("sort-by", Box::new(sort_by::sort_by)), command("sort-by", Box::new(sort_by::sort_by)),
Arc::new(Remove), static_command(Get),
Arc::new(Open), static_command(Cd),
Arc::new(Where), static_command(Remove),
Arc::new(Config), static_command(Open),
Arc::new(SkipWhile), static_command(Where),
]); static_command(Config),
static_command(SkipWhile),
context.add_sinks(vec![ static_command(Clip),
sink("autoview", Box::new(autoview::autoview)), static_command(Autoview),
sink("clip", Box::new(clip::clip)), // command("save", Box::new(save::save)),
sink("save", Box::new(save::save)), // command("table", Box::new(table::table)),
sink("table", Box::new(table::table)), // command("vtable", Box::new(vtable::vtable)),
sink("vtable", Box::new(vtable::vtable)),
]); ]);
} }
let _ = load_plugins(&mut context); let _ = load_plugins(&mut context);
@ -341,11 +331,13 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
.map_err(|err| (line.clone(), err))?; .map_err(|err| (line.clone(), err))?;
match pipeline.commands.last() { match pipeline.commands.last() {
Some(ClassifiedCommand::Sink(_)) => {}
Some(ClassifiedCommand::External(_)) => {} Some(ClassifiedCommand::External(_)) => {}
_ => pipeline.commands.push(ClassifiedCommand::Sink(SinkCommand { _ => pipeline
command: sink("autoview", Box::new(autoview::autoview)), .commands
.push(ClassifiedCommand::Internal(InternalCommand {
command: static_command(autoview::Autoview),
name_span: None, name_span: None,
source_map: ctx.source_map,
args: hir::Call::new( args: hir::Call::new(
Box::new(hir::Expression::synthetic_string("autoview")), Box::new(hir::Expression::synthetic_string("autoview")),
None, None,
@ -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::Internal(left)),
Some(ClassifiedCommand::External(_)), Some(ClassifiedCommand::External(_)),
@ -485,7 +465,7 @@ fn classify_command(
match context.has_command(name) { match context.has_command(name) {
true => { true => {
let command = context.get_command(name); let command = context.get_command(name);
let config = command.config(); let config = command.signature();
trace!(target: "nu::build_pipeline", "classifying {:?}", config); trace!(target: "nu::build_pipeline", "classifying {:?}", config);
@ -498,20 +478,8 @@ fn classify_command(
args, args,
})) }))
} }
false => match context.has_sink(name) { false => match context.get_command(name).as_ref() {
true => { Command::Static(command) => {
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 => {
let arg_list_strings: Vec<Spanned<String>> = match call.children() { 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.iter().map(|i| i.as_external_arg(source)).collect(),
Some(args) => args Some(args) => args

View File

@ -42,8 +42,15 @@ crate mod trim;
crate mod vtable; crate mod vtable;
crate mod where_; 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 config::Config;
crate use get::Get;
crate use open::Open; crate use open::Open;
crate use rm::Remove; crate use rm::Remove;
crate use skip_while::SkipWhile; crate use skip_while::SkipWhile;

View File

@ -1,11 +1,31 @@
use crate::commands::command::SinkCommandArgs; use crate::commands::StaticCommand;
use crate::context::{SourceMap, SpanSource}; use crate::context::{SourceMap, SpanSource};
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::format::GenericView; use crate::format::GenericView;
use crate::prelude::*; use crate::prelude::*;
use std::path::Path; 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 args.input.len() > 0 {
if let Spanned { if let Spanned {
item: Value::Binary(_), 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 { fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {

View File

@ -1,27 +1,54 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::prelude::*; use crate::prelude::*;
use std::env; use std::env;
use std::path::PathBuf;
pub fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub struct Cd;
let env = args.env.clone();
let env = env.lock().unwrap();
let args = args.evaluate_once(registry)?;
let cwd = env.path().to_path_buf();
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() { None => match dirs::home_dir() {
Some(o) => o, Some(o) => o,
_ => { _ => {
return Err(ShellError::maybe_labeled_error( return Err(ShellError::maybe_labeled_error(
"Can not change to home directory", "Can not change to home directory",
"can not go to home", "can not go to home",
args.name_span(), context.name,
)) ))
} }
}, },
Some(v) => { Some(v) => {
let target = v.as_string()?; // let target = v.item.as_string()?;
match dunce::canonicalize(cwd.join(target).as_path()) { match dunce::canonicalize(cwd.join(&v.item()).as_path()) {
Ok(p) => p, Ok(p) => p,
Err(_) => { Err(_) => {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
@ -38,11 +65,11 @@ pub fn cd(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
match env::set_current_dir(&path) { match env::set_current_dir(&path) {
Ok(_) => {} Ok(_) => {}
Err(_) => { Err(_) => {
if args.len() > 0 { if let Some(path) = target {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"Can not change to directory", "Can not change to directory",
"directory not found", "directory not found",
args.nth(0).unwrap().span.clone(), path.span,
)); ));
} else { } else {
return Err(ShellError::string("Can not change to directory")); return Err(ShellError::string("Can not change to directory"));

View File

@ -1,6 +1,5 @@
use crate::commands::command::Sink; use crate::commands::Command;
use crate::context::SourceMap; use crate::context::SourceMap;
use crate::evaluate::Scope;
use crate::parser::{hir, Span, Spanned, TokenNode}; use crate::parser::{hir, Span, Spanned, TokenNode};
use crate::prelude::*; use crate::prelude::*;
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
@ -83,7 +82,6 @@ crate enum ClassifiedCommand {
#[allow(unused)] #[allow(unused)]
Expr(TokenNode), Expr(TokenNode),
Internal(InternalCommand), Internal(InternalCommand),
Sink(SinkCommand),
External(ExternalCommand), External(ExternalCommand),
} }
@ -93,34 +91,13 @@ impl ClassifiedCommand {
match self { match self {
ClassifiedCommand::Expr(token) => token.span(), ClassifiedCommand::Expr(token) => token.span(),
ClassifiedCommand::Internal(internal) => internal.name_span.into(), ClassifiedCommand::Internal(internal) => internal.name_span.into(),
ClassifiedCommand::Sink(sink) => sink.name_span.into(),
ClassifiedCommand::External(external) => external.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 struct InternalCommand {
crate command: Arc<dyn Command>, crate command: Arc<Command>,
crate name_span: Option<Span>, crate name_span: Option<Span>,
crate source_map: SourceMap, crate source_map: SourceMap,
crate args: hir::Call, crate args: hir::Call,
@ -142,14 +119,16 @@ impl InternalCommand {
let objects: InputStream = let objects: InputStream =
trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects); trace_stream!(target: "nu::trace_stream::internal", "input" = input.objects);
let result = context.run_command( let result = context
.run_command(
self.command, self.command,
self.name_span.clone(), self.name_span.clone(),
self.source_map, self.source_map,
self.args, self.args,
source, source,
objects, objects,
)?; )
.await?;
let mut result = result.values; let mut result = result.values;

View File

@ -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::errors::{labelled, ShellError};
use crate::prelude::*;
use clipboard::{ClipboardContext, ClipboardProvider}; 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 clip_context: ClipboardContext = ClipboardProvider::new().unwrap();
let mut new_copy_data = String::new(); let mut new_copy_data = String::new();
if args.input.len() > 0 { if input.len() > 0 {
let mut first = true; let mut first = true;
for i in args.input.iter() { for i in input.iter() {
if !first { if !first {
new_copy_data.push_str("\n"); new_copy_data.push_str("\n");
} else { } else {
first = false; first = false;
} }
let string = i.as_string().map_err(labelled( let s = i.as_string().map_err(labelled(
args.name_span(), name,
"Given non-string data", "Given non-string data",
"expected strings from pipeline", "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); 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(); clip_context.set_contents(new_copy_data).unwrap();
Ok(()) OutputStream::empty()
} }

View File

@ -3,8 +3,9 @@ use crate::errors::ShellError;
use crate::evaluate::Scope; use crate::evaluate::Scope;
use crate::object::Value; use crate::object::Value;
use crate::parser::hir; use crate::parser::hir;
use crate::parser::{registry, Span, Spanned}; use crate::parser::{registry, ConfigDeserializer, Span, Spanned};
use crate::prelude::*; use crate::prelude::*;
use derive_new::new;
use getset::Getters; use getset::Getters;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
@ -80,6 +81,67 @@ impl CommandArgs {
pub fn name_span(&self) -> Option<Span> { pub fn name_span(&self) -> Option<Span> {
self.call_info.name_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 { pub struct EvaluatedStaticCommandArgs {
@ -120,6 +182,12 @@ impl EvaluatedStaticCommandArgs {
(input, args.call_info.args) (input, args.call_info.args)
} }
pub fn split(self) -> (InputStream, EvaluatedCommandArgs) {
let EvaluatedStaticCommandArgs { args, input } = self;
(input, args)
}
} }
#[derive(Getters)] #[derive(Getters)]
@ -155,7 +223,7 @@ impl EvaluatedFilterCommandArgs {
} }
} }
#[derive(Getters)] #[derive(Getters, new)]
#[get = "crate"] #[get = "crate"]
pub struct EvaluatedCommandArgs { pub struct EvaluatedCommandArgs {
pub host: Arc<Mutex<dyn Host>>, pub host: Arc<Mutex<dyn Host>>,
@ -184,24 +252,21 @@ impl EvaluatedCommandArgs {
self.call_info.args.get(name) 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)] #[allow(unused)]
pub fn has(&self, name: &str) -> bool { pub fn has(&self, name: &str) -> bool {
self.call_info.args.has(name) 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)] #[derive(Debug, Serialize, Deserialize)]
pub enum CommandAction { pub enum CommandAction {
ChangePath(PathBuf), ChangePath(PathBuf),
@ -241,38 +306,56 @@ impl ReturnSuccess {
} }
} }
pub trait Command: Send + Sync { pub trait StaticCommand: Send + Sync {
fn name(&self) -> &str;
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &registry::CommandRegistry, registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError>; ) -> Result<OutputStream, ShellError>;
fn name(&self) -> &str;
fn config(&self) -> registry::CommandConfig { fn signature(&self) -> Signature {
registry::CommandConfig { Signature {
name: self.name().to_string(), name: self.name().to_string(),
positional: vec![], positional: vec![],
rest_positional: true, rest_positional: true,
named: indexmap::IndexMap::new(), named: indexmap::IndexMap::new(),
is_filter: true, is_filter: true,
is_sink: false,
} }
} }
} }
pub trait Sink { pub enum Command {
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError>; Static(Arc<dyn StaticCommand>),
fn name(&self) -> &str; }
fn config(&self) -> registry::CommandConfig { impl Command {
registry::CommandConfig { pub fn name(&self) -> &str {
name: self.name().to_string(), match self {
positional: vec![], Command::Static(command) => command.name(),
rest_positional: true, }
named: indexmap::IndexMap::new(), }
is_filter: false,
is_sink: true, 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: &registry::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>, func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
} }
impl Command for FnFilterCommand { impl StaticCommand for FnFilterCommand {
fn name(&self) -> &str { fn name(&self) -> &str {
&self.name &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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -347,10 +434,6 @@ impl Command for FnRawCommand {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
(self.func)(args, registry) (self.func)(args, registry)
} }
fn name(&self) -> &str {
&self.name
}
} }
pub fn command( pub fn command(
@ -360,45 +443,24 @@ pub fn command(
+ Send + Send
+ Sync, + Sync,
>, >,
) -> Arc<dyn Command> { ) -> Arc<Command> {
Arc::new(FnRawCommand { Arc::new(Command::Static(Arc::new(FnRawCommand {
name: name.to_string(), name: name.to_string(),
func, func,
}) })))
}
pub fn static_command(command: impl StaticCommand + 'static) -> Arc<Command> {
Arc::new(Command::Static(Arc::new(command)))
} }
#[allow(unused)] #[allow(unused)]
pub fn filter( pub fn filter(
name: &str, name: &str,
func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>, func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
) -> Arc<dyn Command> { ) -> Arc<Command> {
Arc::new(FnFilterCommand { Arc::new(Command::Static(Arc::new(FnFilterCommand {
name: name.to_string(), name: name.to_string(),
func, 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,
})
} }

View File

@ -1,57 +1,61 @@
use crate::prelude::*; use crate::prelude::*;
use crate::commands::EvaluatedStaticCommandArgs; use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{config, Value}; use crate::object::{config, Value};
use crate::parser::hir::SyntaxType; use crate::parser::hir::SyntaxType;
use crate::parser::registry::{self, CommandConfig, NamedType}; use crate::parser::registry::{self};
use indexmap::IndexMap;
use log::trace;
use std::iter::FromIterator; use std::iter::FromIterator;
pub struct Config; 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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &registry::CommandRegistry, registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; args.process(registry, config)?.run()
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,
}
} }
} }
pub fn config(args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> { pub fn config(
let mut result = crate::object::config::config(args.name_span())?; 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); if let Some(v) = get {
trace!("{:#?}", args.call_args().named); let key = v.to_string();
if let Some(v) = args.get("get") {
let key = v.as_string()?;
let value = result let value = result
.get(&key) .get(&key)
.ok_or_else(|| ShellError::string(&format!("Missing key {} in config", 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 Some((key, value)) = set {
if let Ok((key, value)) = v.as_pair() { result.insert(key.to_string(), value.clone());
result.insert(key.as_string()?.to_string(), value.clone());
config::write_config(&result)?; config::write_config(&result)?;
return Ok( return Ok(stream![Spanned::from_item(
stream![Spanned::from_item(Value::Object(result.into()), v.span())] Value::Object(result.into()),
.from_input_stream(), value.span()
); )]
} .from_input_stream());
} }
if let Some(c) = args.get("clear") { if let Spanned { item: true, span } = clear {
result.clear(); result.clear();
config::write_config(&result)?; config::write_config(&result)?;
return Ok( 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") { if let Spanned { item: true, span } = path {
let key = v.as_string()?; 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) { if result.contains_key(&key) {
result.remove(&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()); return Ok(obj.from_input_stream());
} }
if args.len() == 0 { return Ok(vec![Value::Object(result.into()).spanned(name)].into());
return Ok(vec![Value::Object(result.into()).spanned(args.name_span())].into());
}
Err(ShellError::string(format!("Unimplemented")))
} }

View File

@ -2,7 +2,7 @@ use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value}; use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::prelude::*; 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(); let span = span.into();
match v { match v {

View File

@ -1,9 +1,33 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use crate::parser::Span;
use crate::prelude::*; 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; let mut current = obj;
for p in path.split(".") { for p in path.split(".") {
match current.get_data_by_key(p) { 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( return Err(ShellError::labeled_error(
"Unknown field", "Unknown field",
"object missing 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()) Ok(current.clone())
} }
pub fn get(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> { pub fn get(
let args = args.evaluate_once(registry)?; GetArgs { rest: fields }: GetArgs,
let span = args.name_span(); RunnableContext { input, .. }: RunnableContext,
let len = args.len(); ) -> Result<OutputStream, ShellError> {
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;
// If it's a number, get the row instead of the column // If it's a number, get the row instead of the column
if let Ok(amount) = amount { // if let Some(amount) = amount {
return Ok(input.values.skip(amount as u64).take(1).from_input_stream()); // 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?;
let stream = input let stream = input
.values .values
.map(move |item| { .map(move |item| {
let mut result = VecDeque::new(); let mut result = VecDeque::new();
for field in &fields { for field in &fields {
match get_member(&field.0, field.1, &item) { match get_member(field, &item) {
Ok(Spanned { Ok(Spanned {
item: Value::List(l), item: Value::List(l),
.. ..

View File

@ -12,7 +12,7 @@ macro_rules! command {
Named { $export:tt $args:ident $body:block } Named { $export:tt $args:ident $body:block }
Positional { $($number:tt)* } Positional { $($number:tt)* }
Rest {} Rest {}
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -52,8 +52,8 @@ macro_rules! command {
stringify!($config_name) stringify!($config_name)
} }
fn config(&self) -> $crate::parser::registry::CommandConfig { fn config(&self) -> $crate::parser::registry::Signature {
$crate::parser::registry::CommandConfig { $crate::parser::registry::Signature {
name: self.name().to_string(), name: self.name().to_string(),
positional: vec![$($mandatory_positional)*], positional: vec![$($mandatory_positional)*],
rest_positional: false, rest_positional: false,
@ -82,7 +82,7 @@ macro_rules! command {
Named { $export:tt $args:ident $body:block } Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* } Positional { $($positional_count:tt)* }
Rest { -- $param_name:ident : Switch , $($rest:tt)* } Rest { -- $param_name:ident : Switch , $($rest:tt)* }
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -102,7 +102,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { $($positional_count)* + 1 } Positional { $($positional_count)* + 1 }
Rest { $($rest)* } Rest { $($rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ], mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ], optional_positional: vec![ $($optional_positional)* ],
@ -132,7 +132,7 @@ macro_rules! command {
Named { $export:tt $args:ident $body:block } Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* } Positional { $($positional_count:tt)* }
Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* } Rest { -- $param_name:ident : $param_kind:ty , $($rest:tt)* }
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -152,7 +152,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { $($positional_count)* + 1 } Positional { $($positional_count)* + 1 }
Rest { $($rest)* } Rest { $($rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ], mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ], optional_positional: vec![ $($optional_positional)* ],
@ -182,7 +182,7 @@ macro_rules! command {
Named { $export:tt $args:ident $body:block } Named { $export:tt $args:ident $body:block }
Positional { $($positional_count:tt)* } Positional { $($positional_count:tt)* }
Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* } Rest { -- $param_name:ident ? : $param_kind:ty , $($rest:tt)* }
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -202,7 +202,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { $($positional_count)* + 1 } Positional { $($positional_count)* + 1 }
Rest { $($rest)* } Rest { $($rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* ], mandatory_positional: vec![ $($mandatory_positional)* ],
optional_positional: vec![ $($optional_positional)* ], optional_positional: vec![ $($optional_positional)* ],
@ -232,7 +232,7 @@ macro_rules! command {
Named { $export:ident $args:ident $body:block } Named { $export:ident $args:ident $body:block }
Positional { $($positional_count:tt)* } Positional { $($positional_count:tt)* }
Rest { $param_name:ident : Block , $($rest:tt)* } Rest { $param_name:ident : Block , $($rest:tt)* }
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -255,7 +255,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { $($positional_count)* + 1 } Positional { $($positional_count)* + 1 }
Rest { $($rest)* } Rest { $($rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory_block( mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory_block(
stringify!($param_name) stringify!($param_name)
@ -287,7 +287,7 @@ macro_rules! command {
Named { $export:ident $args:ident $body:block } Named { $export:ident $args:ident $body:block }
Positional { $($positional_count:tt)* } Positional { $($positional_count:tt)* }
Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* } Rest { $param_name:ident : $param_kind:ty , $($rest:tt)* }
CommandConfig { Signature {
name: $config_name:tt, name: $config_name:tt,
mandatory_positional: vec![ $($mandatory_positional:tt)* ], mandatory_positional: vec![ $($mandatory_positional:tt)* ],
optional_positional: vec![ $($optional_positional:tt)* ], optional_positional: vec![ $($optional_positional:tt)* ],
@ -310,7 +310,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { $($positional_count)* + 1 } Positional { $($positional_count)* + 1 }
Rest { $($rest)* } Rest { $($rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory( mandatory_positional: vec![ $($mandatory_positional)* $crate::parser::registry::PositionalType::mandatory(
stringify!($param_name), <$param_kind>::syntax_type() stringify!($param_name), <$param_kind>::syntax_type()
@ -341,7 +341,7 @@ macro_rules! command {
Named { $export $args $body } Named { $export $args $body }
Positional { 0 } Positional { 0 }
Rest { $($command_rest)* } Rest { $($command_rest)* }
CommandConfig { Signature {
name: $config_name, name: $config_name,
mandatory_positional: vec![], mandatory_positional: vec![],
optional_positional: vec![], optional_positional: vec![],
@ -377,11 +377,11 @@ macro_rules! command {
// stringify!($name) // stringify!($name)
// } // }
// fn config(&self) -> CommandConfig { // fn config(&self) -> Signature {
// let mut named: IndexMap<String, NamedType> = IndexMap::new(); // let mut named: IndexMap<String, NamedType> = IndexMap::new();
// named.insert(stringify!($param).to_string(), NamedType::$kind); // named.insert(stringify!($param).to_string(), NamedType::$kind);
// CommandConfig { // Signature {
// name: self.name().to_string(), // name: self.name().to_string(),
// mandatory_positional: vec![], // mandatory_positional: vec![],
// optional_positional: vec![], // optional_positional: vec![],

View File

@ -1,9 +1,10 @@
use crate::commands::StaticCommand;
use crate::context::SpanSource; use crate::context::SpanSource;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::parser::hir::SyntaxType; use crate::parser::hir::SyntaxType;
use crate::parser::parse::span::Span; use crate::parser::parse::span::Span;
use crate::parser::registry::{self, CommandConfig, NamedType}; use crate::parser::registry::{self, Signature};
use crate::prelude::*; use crate::prelude::*;
use mime::Mime; use mime::Mime;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -12,19 +13,37 @@ use uuid::Uuid;
pub struct Open; 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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &registry::CommandRegistry, registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let env = args.env.clone(); args.process(registry, run)?.run()
let args = args.evaluate_once(registry)?; }
let path = <Spanned<PathBuf>>::extract(args.expect_nth(0)?)?; }
let raw = args.has("raw");
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 cwd = env.lock().unwrap().path().to_path_buf();
let full_path = PathBuf::from(cwd); let full_path = PathBuf::from(cwd);
@ -50,7 +69,7 @@ impl Command for Open {
match contents { match contents {
Value::Primitive(Primitive::String(string)) => { Value::Primitive(Primitive::String(string)) => {
let value = parse_as_value(file_extension, string, contents_span, span)?; let value = parse_as_value(file_extension, string, contents_span, name)?;
match value { match value {
Spanned { Spanned {
@ -71,18 +90,6 @@ impl Command for Open {
Ok(stream.boxed().to_output_stream()) 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()
}
}
// command! { // command! {
// Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) { // Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) {
// let span = args.name_span(); // let span = args.name_span();

View File

@ -1,7 +1,9 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::registry; use crate::parser::registry;
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
use futures_async_stream::async_stream_block;
use serde::{self, Deserialize, Serialize}; use serde::{self, Deserialize, Serialize};
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufReader; use std::io::BufReader;
@ -37,10 +39,18 @@ pub enum NuResult {
pub struct PluginCommand { pub struct PluginCommand {
name: String, name: String,
path: String, path: String,
config: registry::CommandConfig, config: registry::Signature,
}
impl StaticCommand for PluginCommand {
fn name(&self) -> &str {
&self.name
}
fn signature(&self) -> registry::Signature {
self.config.clone()
} }
impl Command for PluginCommand {
fn run( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
@ -48,29 +58,36 @@ impl Command for PluginCommand {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
filter_plugin(self.path.clone(), args, registry) filter_plugin(self.path.clone(), args, registry)
} }
fn name(&self) -> &str {
&self.name
}
fn config(&self) -> registry::CommandConfig {
self.config.clone()
}
} }
#[derive(new)] #[derive(new)]
pub struct PluginSink { pub struct PluginSink {
name: String,
path: String, path: String,
config: registry::CommandConfig, config: registry::Signature,
} }
impl Sink for PluginSink { impl StaticCommand for PluginSink {
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError> { fn run(
sink_plugin(self.path.clone(), args) &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 { fn name(&self) -> &str {
&self.name &self.config.name
} }
fn config(&self) -> registry::CommandConfig {
fn signature(&self) -> registry::Signature {
self.config.clone() self.config.clone()
} }
} }
@ -191,9 +208,10 @@ pub fn filter_plugin(
Ok(stream.to_output_stream()) 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; //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 request_raw = serde_json::to_string(&request).unwrap();
let mut tmpfile = tempfile::NamedTempFile::new()?; let mut tmpfile = tempfile::NamedTempFile::new()?;
let _ = writeln!(tmpfile, "{}", request_raw); let _ = writeln!(tmpfile, "{}", request_raw);
@ -206,5 +224,5 @@ pub fn sink_plugin(path: String, args: SinkCommandArgs) -> Result<(), ShellError
let _ = child.wait(); let _ = child.wait();
Ok(()) Ok(OutputStream::empty())
} }

View File

@ -1,63 +1,57 @@
use crate::commands::EvaluatedStaticCommandArgs; use crate::commands::{EvaluatedStaticCommandArgs, StaticCommand};
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::hir::SyntaxType; use crate::parser::hir::SyntaxType;
use crate::parser::registry::{CommandConfig, NamedType, PositionalType}; use crate::parser::registry::{NamedType, PositionalType};
use crate::prelude::*; use crate::prelude::*;
use indexmap::IndexMap; use indexmap::IndexMap;
use std::path::PathBuf;
pub struct Remove; 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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &CommandRegistry, registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let env = args.env.clone(); args.process(registry, rm)?.run()
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,
}
} }
} }
pub fn rm( pub fn rm(
args: EvaluatedStaticCommandArgs, RemoveArgs { path, recursive }: RemoveArgs,
env: Arc<Mutex<Environment>>, context: RunnableContext,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let mut full_path = env.lock().unwrap().path().to_path_buf(); let mut full_path = context.cwd();
match args match path.item.to_str().unwrap() {
.nth(0)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
.as_string()?
.as_str()
{
"." | ".." => return Err(ShellError::string("\".\" and \"..\" may not be removed")), "." | ".." => return Err(ShellError::string("\".\" and \"..\" may not be removed")),
file => full_path.push(file), file => full_path.push(file),
} }
if full_path.is_dir() { if full_path.is_dir() {
if !args.has("recursive") { if !recursive {
return Err(ShellError::labeled_error( return Err(ShellError::maybe_labeled_error(
"is a directory", "is a directory",
"", "",
args.name_span().unwrap(), context.name,
)); ));
} }
std::fs::remove_dir_all(&full_path).expect("can not remove directory"); std::fs::remove_dir_all(&full_path).expect("can not remove directory");

View File

@ -1,88 +1,103 @@
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_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_json::value_to_json_value;
use crate::commands::to_toml::value_to_toml_value; use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value; use crate::commands::to_yaml::value_to_yaml_value;
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value}; use crate::object::{Primitive, Value};
use crate::parser::Spanned; use crate::parser::Spanned;
use crate::prelude::*;
use futures_async_stream::async_stream_block;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> { pub struct Save;
if args.call_info.args.positional.is_none() {
return Err(ShellError::maybe_labeled_error( #[derive(Deserialize)]
"Save requires a filepath", struct SaveArgs {
"needs path", path: Spanned<PathBuf>,
args.name_span(), raw: bool,
));
} }
let positional = match args.call_info.args.positional { impl StaticCommand for Save {
None => return Err(ShellError::string("save requires a filepath")), fn name(&self) -> &str {
Some(p) => p, "save"
};
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) { fn signature(&self) -> Signature {
Some(Spanned { Signature::build("save")
item: Value::Primitive(Primitive::String(s)), .required("path", SyntaxType::Path)
.. .switch("raw")
}) if s == "--raw" => true, .sink()
_ => false, }
};
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() { let contents = match full_path.extension() {
Some(x) if x == "csv" && !save_raw => { Some(x) if x == "csv" && !save_raw => {
if args.input.len() != 1 { if input.len() != 1 {
return Err(ShellError::string( return Err(ShellError::string(
"saving to csv requires a single object (or use --raw)", "saving to csv requires a single object (or use --raw)",
)); ));
} }
to_csv_to_string(&value_to_csv_value(&args.input[0])).unwrap() to_csv_to_string(&value_to_csv_value(&input[0])).unwrap()
} }
Some(x) if x == "toml" && !save_raw => { Some(x) if x == "toml" && !save_raw => {
if args.input.len() != 1 { if input.len() != 1 {
return Err(ShellError::string( return Err(ShellError::string(
"saving to toml requires a single object (or use --raw)", "saving to toml requires a single object (or use --raw)",
)); ));
} }
toml::to_string(&value_to_toml_value(&args.input[0])).unwrap() toml::to_string(&value_to_toml_value(&input[0])).unwrap()
} }
Some(x) if x == "json" && !save_raw => { Some(x) if x == "json" && !save_raw => {
if args.input.len() != 1 { if input.len() != 1 {
return Err(ShellError::string( return Err(ShellError::string(
"saving to json requires a single object (or use --raw)", "saving to json requires a single object (or use --raw)",
)); ));
} }
serde_json::to_string(&value_to_json_value(&args.input[0])).unwrap() serde_json::to_string(&value_to_json_value(&input[0])).unwrap()
} }
Some(x) if x == "yml" && !save_raw => { Some(x) if x == "yml" && !save_raw => {
if args.input.len() != 1 { if input.len() != 1 {
return Err(ShellError::string( return Err(ShellError::string(
"saving to yml requires a single object (or use --raw)", "saving to yml requires a single object (or use --raw)",
)); ));
} }
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap() serde_yaml::to_string(&value_to_yaml_value(&input[0])).unwrap()
} }
Some(x) if x == "yaml" && !save_raw => { Some(x) if x == "yaml" && !save_raw => {
if args.input.len() != 1 { if input.len() != 1 {
return Err(ShellError::string( return Err(ShellError::string(
"saving to yaml requires a single object (or use --raw)", "saving to yaml requires a single object (or use --raw)",
)); ));
} }
serde_yaml::to_string(&value_to_yaml_value(&args.input[0])).unwrap() serde_yaml::to_string(&value_to_yaml_value(&input[0])).unwrap()
} }
_ => { _ => {
let mut save_data = String::new(); let mut save_data = String::new();
if args.input.len() > 0 { if input.len() > 0 {
let mut first = true; let mut first = true;
for i in args.input.iter() { for i in input.iter() {
if !first { if !first {
save_data.push_str("\n"); save_data.push_str("\n");
} else { } else {
@ -96,5 +111,9 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
}; };
let _ = std::fs::write(full_path, contents); let _ = std::fs::write(full_path, contents);
Ok(()) };
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
Ok(OutputStream::from(stream))
} }

View File

@ -1,54 +1,40 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::parser::registry::CommandConfig;
use crate::parser::registry::PositionalType;
use crate::prelude::*; use crate::prelude::*;
pub struct SkipWhile; 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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &CommandRegistry, registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
skip_while(args, registry) args.process(registry, skip_while)?.run()
}
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,
}
} }
} }
pub fn skip_while( pub fn skip_while(
args: CommandArgs, SkipWhileArgs { condition }: SkipWhileArgs,
registry: &CommandRegistry, RunnableContext { input, .. }: RunnableContext,
) -> Result<OutputStream, ShellError> { ) -> 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 objects = input.values.skip_while(move |item| {
let result = block.invoke(&item); let result = condition.invoke(&item);
let return_value = match result { let return_value = match result {
Ok(v) if v.is_true() => true, Ok(v) if v.is_true() => true,

View File

@ -1,9 +1,8 @@
use crate::commands::command::SinkCommandArgs;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::format::TableView; use crate::format::TableView;
use crate::prelude::*; use crate::prelude::*;
pub fn table(args: SinkCommandArgs) -> Result<(), ShellError> { pub fn table(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
if args.input.len() > 0 { if args.input.len() > 0 {
let mut host = args.ctx.host.lock().unwrap(); let mut host = args.ctx.host.lock().unwrap();
let view = TableView::from_list(&args.input); let view = TableView::from_list(&args.input);

View File

@ -1,9 +1,8 @@
use crate::commands::command::SinkCommandArgs;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::format::VTableView; use crate::format::VTableView;
use crate::prelude::*; use crate::prelude::*;
pub fn vtable(args: SinkCommandArgs) -> Result<(), ShellError> { pub fn vtable(args: CommandArgs, context: RunnableContext) -> Result<(), ShellError> {
if args.input.len() > 0 { if args.input.len() > 0 {
let mut host = args.ctx.host.lock().unwrap(); let mut host = args.ctx.host.lock().unwrap();
let view = VTableView::from_list(&args.input); let view = VTableView::from_list(&args.input);

View File

@ -1,28 +1,46 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::base as value; use crate::object::base as value;
use crate::parser::hir::SyntaxType; use crate::parser::hir::SyntaxType;
use crate::parser::registry::{self, CommandConfig, PositionalType}; use crate::parser::registry;
use crate::prelude::*; use crate::prelude::*;
use futures::future::ready; use futures::future::ready;
use indexmap::IndexMap; use serde::Deserialize;
use log::trace;
pub struct Where; 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( fn run(
&self, &self,
args: CommandArgs, args: CommandArgs,
registry: &registry::CommandRegistry, registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?; args.process(registry, run)?.run()
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 fn run(
WhereArgs { condition }: WhereArgs,
context: RunnableContext,
) -> Result<OutputStream, ShellError> {
Ok(context
.input
.values .values
.filter_map(move |item| { .filter_map(move |item| {
let result = condition.invoke(&item); let result = condition.invoke(&item);
@ -38,38 +56,3 @@ impl Command for Where {
.boxed() .boxed()
.to_output_stream()) .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,
}
}
}
// command! {
// Where as where(args, condition: Block,) {
// let input = args.input;
// let input: InputStream = trace_stream!(target: "nu::trace_stream::where", "where input" = input);
// 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)
// })
// }
// }

View File

@ -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::parser::{hir, registry, Span};
use crate::prelude::*; use crate::prelude::*;
@ -37,7 +37,7 @@ impl SourceMap {
#[derive(Clone, new)] #[derive(Clone, new)]
pub struct CommandRegistry { pub struct CommandRegistry {
#[new(value = "Arc::new(Mutex::new(IndexMap::default()))")] #[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 { 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(); let registry = self.registry.lock().unwrap();
registry.get(name).map(|c| c.clone()) registry.get(name).map(|c| c.clone())
@ -59,7 +59,7 @@ impl CommandRegistry {
registry.contains_key(name) 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(); let mut registry = self.registry.lock().unwrap();
registry.insert(name.into(), command); registry.insert(name.into(), command);
} }
@ -73,7 +73,6 @@ impl CommandRegistry {
#[derive(Clone)] #[derive(Clone)]
pub struct Context { pub struct Context {
registry: CommandRegistry, registry: CommandRegistry,
sinks: IndexMap<String, Arc<dyn Sink>>,
crate source_map: SourceMap, crate source_map: SourceMap,
crate host: Arc<Mutex<dyn Host + Send>>, crate host: Arc<Mutex<dyn Host + Send>>,
crate env: Arc<Mutex<Environment>>, crate env: Arc<Mutex<Environment>>,
@ -87,57 +86,22 @@ impl Context {
crate fn basic() -> Result<Context, Box<dyn Error>> { crate fn basic() -> Result<Context, Box<dyn Error>> {
Ok(Context { Ok(Context {
registry: CommandRegistry::new(), registry: CommandRegistry::new(),
sinks: indexmap::IndexMap::new(),
source_map: SourceMap::new(), source_map: SourceMap::new(),
host: Arc::new(Mutex::new(crate::env::host::BasicHost)), host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
env: Arc::new(Mutex::new(Environment::basic()?)), 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 { for command in commands {
self.registry.insert(command.name().to_string(), command); 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) { pub fn add_span_source(&mut self, uuid: Uuid, span_source: SpanSource) {
self.source_map.insert(uuid, span_source); 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 { pub fn clone_commands(&self) -> CommandRegistry {
self.registry.clone() self.registry.clone()
} }
@ -146,13 +110,13 @@ impl Context {
self.registry.has(name) 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() self.registry.get_command(name).unwrap()
} }
crate fn run_command( crate async fn run_command(
&mut self, &mut self,
command: Arc<dyn Command>, command: Arc<Command>,
name_span: Option<Span>, name_span: Option<Span>,
source_map: SourceMap, source_map: SourceMap,
args: hir::Call, args: hir::Call,
@ -161,7 +125,7 @@ impl Context {
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let command_args = self.command_args(args, input, source, source_map, name_span); 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( fn call_info(

View File

@ -62,6 +62,15 @@ pub struct ShellError {
cause: Option<Box<ProximateShellError>>, 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 { impl ShellError {
crate fn type_error( crate fn type_error(
expected: impl Into<String>, 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 { impl std::convert::From<subprocess::PopenError> for ShellError {
fn from(input: subprocess::PopenError) -> ShellError { fn from(input: subprocess::PopenError) -> ShellError {
ProximateShellError::String(StringError { ProximateShellError::String(StringError {

View File

@ -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( RawExpression::Block(block) => Ok(Spanned::from_item(
Value::Block(Block::new(block.clone(), source.clone(), *expr.span())), Value::Block(Block::new(block.clone(), source.clone(), *expr.span())),
expr.span(), expr.span(),

View File

@ -1,11 +1,15 @@
#![feature(crate_visibility_modifier)] #![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)] #![feature(in_band_lifetimes)]
#![feature(async_await)] #![feature(async_await)]
#![feature(generators)]
#![feature(try_trait)] #![feature(try_trait)]
#![feature(bind_by_move_pattern_guards)] #![feature(bind_by_move_pattern_guards)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(type_ascription)] #![feature(type_ascription)]
#![feature(core_intrinsics)]
#![feature(option_flattening)] #![feature(option_flattening)]
#![feature(specialization)]
#![feature(proc_macro_hygiene)]
#[macro_use] #[macro_use]
mod prelude; mod prelude;
@ -37,4 +41,4 @@ pub use cli::cli;
pub use errors::ShellError; pub use errors::ShellError;
pub use object::base::{Primitive, Value}; pub use object::base::{Primitive, Value};
pub use parser::parse::text::Text; pub use parser::parse::text::Text;
pub use parser::registry::{CommandConfig, EvaluatedArgs, NamedType, PositionalType}; pub use parser::registry::{EvaluatedArgs, NamedType, PositionalType, Signature};

View File

@ -6,6 +6,6 @@ crate mod into;
crate mod process; crate mod process;
crate mod types; crate mod types;
crate use base::{Primitive, Value}; crate use base::{Block, Primitive, Switch, Value};
crate use dict::{Dictionary, SpannedDictBuilder}; crate use dict::{Dictionary, SpannedDictBuilder};
crate use files::dir_entry_dict; crate use files::dir_entry_dict;

View File

@ -10,7 +10,7 @@ use chrono::{DateTime, Utc};
use chrono_humanize::Humanize; use chrono_humanize::Humanize;
use derive_new::new; use derive_new::new;
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::SystemTime; use std::time::SystemTime;
@ -123,42 +123,13 @@ pub struct Operation {
crate right: Value, crate right: Value,
} }
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, new)] #[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Serialize, Deserialize, new)]
pub struct Block { pub struct Block {
crate expressions: Vec<hir::Expression>, crate expressions: Vec<hir::Expression>,
crate source: Text, crate source: Text,
crate span: Span, 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 { impl Block {
pub fn invoke(&self, value: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> { pub fn invoke(&self, value: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
let scope = Scope::new(value.clone()); 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 { pub enum Switch {
Present, Present,
Absent, Absent,

View File

@ -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::errors::ShellError;
use crate::object::{Dictionary, Value};
use crate::prelude::*; use crate::prelude::*;
use app_dirs::*; use app_dirs::*;
use indexmap::IndexMap; use indexmap::IndexMap;
use log::trace; use log::trace;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fs::{self, OpenOptions}; use std::fs::{self, OpenOptions};
use std::io; use std::io;
use std::path::Path; use std::path::{Path, PathBuf};
const APP_INFO: AppInfo = AppInfo { const APP_INFO: AppInfo = AppInfo {
name: "nu", name: "nu",
@ -16,7 +19,14 @@ const APP_INFO: AppInfo = AppInfo {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
struct Config { struct Config {
#[serde(flatten)] #[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> { 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"); let filename = location.join("config.toml");
touch(&filename)?; touch(&filename)?;
let contents = toml::to_string(&Config { let contents = value_to_toml_value(&Value::Object(Dictionary::new(config.clone())));
extra: config.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
})?; let contents = toml::to_string(&contents)?;
fs::write(&filename, &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(|v| v.spanned(span))
.map_err(|err| ShellError::string(&format!("Couldn't read config file:\n{}", err)))?; .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)))?; .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) // A simple implementation of `% touch path` (ignores existing files)

View File

@ -1,16 +1,9 @@
use crate::object::base as value; use crate::object::base as value;
use crate::parser::hir; use crate::parser::hir;
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use log::trace;
use serde_derive::Deserialize;
use std::path::PathBuf; use std::path::PathBuf;
pub trait Type: std::fmt::Debug + Send {
type Extractor: ExtractType;
fn name(&self) -> &'static str;
}
pub trait ExtractType: Sized { pub trait ExtractType: Sized {
fn extract(value: &Spanned<Value>) -> Result<Self, ShellError>; fn extract(value: &Spanned<Value>) -> Result<Self, ShellError>;
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, 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> { impl<T: ExtractType> ExtractType for Spanned<T> {
fn extract(value: &Spanned<Value>) -> Result<Spanned<T>, ShellError> { 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)) 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)] impl ExtractType for Value {
pub struct Any; fn extract(value: &Spanned<Value>) -> Result<Value, ShellError> {
trace!("<Spanned> Extracting {:?} for Value", value);
impl Type for Any { Ok(value.item().clone())
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())
} }
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
Ok(value) 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 { 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> { fn extract(value: &'a Spanned<Value>) -> Result<std::path::PathBuf, ShellError> {
trace!("Extracting {:?} for PathBuf", value);
match &value { match &value {
Spanned { Spanned {
item: Value::Primitive(Primitive::String(p)), 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 { impl ExtractType for i64 {
fn extract(value: &Spanned<Value>) -> Result<i64, ShellError> { fn extract(value: &Spanned<Value>) -> Result<i64, ShellError> {
trace!("Extracting {:?} for i64", value);
match value { match value {
&Spanned { &Spanned {
item: Value::Primitive(Primitive::Int(int)), 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 { impl ExtractType for String {
fn extract(value: &Spanned<Value>) -> Result<String, ShellError> { fn extract(value: &Spanned<Value>) -> Result<String, ShellError> {
trace!("Extracting {:?} for String", value);
match value { match value {
Spanned { Spanned {
item: Value::Primitive(Primitive::String(string)), 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 { impl ExtractType for value::Block {
fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> { fn check(value: &'value Spanned<Value>) -> Result<&'value Spanned<Value>, ShellError> {
trace!("Extracting {:?} for Block", value);
match value { match value {
v @ Spanned { v @ Spanned {
item: Value::Block(_), item: Value::Block(_),

View File

@ -1,3 +1,4 @@
crate mod deserializer;
crate mod hir; crate mod hir;
crate mod parse; crate mod parse;
crate mod parse_command; crate mod parse_command;
@ -5,6 +6,7 @@ crate mod registry;
use crate::errors::ShellError; use crate::errors::ShellError;
crate use deserializer::ConfigDeserializer;
crate use hir::baseline_parse_tokens::baseline_parse_tokens; crate use hir::baseline_parse_tokens::baseline_parse_tokens;
crate use parse::call_node::CallNode; crate use parse::call_node::CallNode;
crate use parse::files::Files; crate use parse::files::Files;

307
src/parser/deserializer.rs Normal file
View 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());
}
}

View File

@ -9,7 +9,7 @@ use crate::parser::{registry, Span, Spanned, Unit};
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
crate use baseline_parse::{baseline_parse_single_token, baseline_parse_token_as_string}; crate use baseline_parse::{baseline_parse_single_token, baseline_parse_token_as_string};
@ -76,6 +76,7 @@ pub enum RawExpression {
Variable(Variable), Variable(Variable),
Binary(Box<Binary>), Binary(Box<Binary>),
Block(Vec<Expression>), Block(Vec<Expression>),
List(Vec<Expression>),
Path(Box<Path>), Path(Box<Path>),
#[allow(unused)] #[allow(unused)]
@ -101,6 +102,7 @@ impl RawExpression {
RawExpression::Literal(literal) => literal.type_name(), RawExpression::Literal(literal) => literal.type_name(),
RawExpression::Synthetic(synthetic) => synthetic.type_name(), RawExpression::Synthetic(synthetic) => synthetic.type_name(),
RawExpression::Variable(..) => "variable", RawExpression::Variable(..) => "variable",
RawExpression::List(..) => "list",
RawExpression::Binary(..) => "binary", RawExpression::Binary(..) => "binary",
RawExpression::Block(..) => "block", RawExpression::Block(..) => "block",
RawExpression::Path(..) => "path", RawExpression::Path(..) => "path",
@ -170,6 +172,15 @@ impl ToDebug for Expression {
write!(f, "}}") 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::Path(p) => write!(f, "{}", p.debug(source)),
RawExpression::Boolean(true) => write!(f, "$yes"), RawExpression::Boolean(true) => write!(f, "$yes"),
RawExpression::Boolean(false) => write!(f, "$no"), RawExpression::Boolean(false) => write!(f, "$no"),

View File

@ -8,7 +8,7 @@ use crate::parser::{
use crate::{SpannedItem, Text}; use crate::{SpannedItem, Text};
use derive_new::new; use derive_new::new;
use log::trace; use log::trace;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub fn baseline_parse_tokens( pub fn baseline_parse_tokens(
token_nodes: &mut TokensIterator<'_>, token_nodes: &mut TokensIterator<'_>,
@ -33,6 +33,7 @@ pub fn baseline_parse_tokens(
#[derive(Debug, Copy, Clone, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum SyntaxType { pub enum SyntaxType {
Any, Any,
List,
Literal, Literal,
Variable, Variable,
Path, Path,
@ -210,7 +211,14 @@ pub fn baseline_parse_delimited(
Ok(Spanned::from_item(expr, token.span())) Ok(Spanned::from_item(expr, token.span()))
} }
Delimiter::Paren => unimplemented!(), 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()))
}
} }
} }

View File

@ -2,7 +2,7 @@ use crate::parser::{hir::Expression, Operator, Spanned};
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
#[derive( #[derive(

View File

@ -4,7 +4,7 @@ use crate::prelude::*;
use derive_new::new; use derive_new::new;
use indexmap::IndexMap; use indexmap::IndexMap;
use log::trace; use log::trace;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]

View File

@ -2,7 +2,7 @@ use crate::parser::{hir::Expression, Spanned};
use crate::prelude::*; use crate::prelude::*;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
#[derive( #[derive(

View File

@ -1,7 +1,7 @@
use crate::parser::Span; use crate::parser::Span;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub enum FlagKind { pub enum FlagKind {

View File

@ -1,5 +1,5 @@
use crate::prelude::*; use crate::prelude::*;
use serde_derive::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;

View File

@ -2,8 +2,8 @@ use crate::prelude::*;
use crate::Text; use crate::Text;
use derive_new::new; use derive_new::new;
use getset::Getters; use getset::Getters;
use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use serde_derive::Deserialize;
use uuid::Uuid; use uuid::Uuid;
#[derive( #[derive(

View File

@ -1,6 +1,6 @@
use serde_derive::{Deserialize, Serialize};
use std::str::FromStr;
use crate::object::base::Value; use crate::object::base::Value;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub enum Unit { pub enum Unit {

View File

@ -1,5 +1,5 @@
use crate::errors::{ArgumentError, ShellError}; 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::{baseline_parse_tokens, CallNode, Span, Spanned};
use crate::parser::{ use crate::parser::{
hir::{self, NamedArguments}, hir::{self, NamedArguments},
@ -9,7 +9,7 @@ use crate::Text;
use log::trace; use log::trace;
pub fn parse_command( pub fn parse_command(
config: &CommandConfig, config: &Signature,
registry: &CommandRegistry, registry: &CommandRegistry,
call: &Spanned<CallNode>, call: &Spanned<CallNode>,
source: &Text, source: &Text,
@ -62,7 +62,7 @@ fn parse_command_head(head: &TokenNode) -> Result<hir::Expression, ShellError> {
} }
fn parse_command_tail( fn parse_command_tail(
config: &CommandConfig, config: &Signature,
registry: &CommandRegistry, registry: &CommandRegistry,
tail: Option<Vec<TokenNode>>, tail: Option<Vec<TokenNode>>,
source: &Text, source: &Text,
@ -197,7 +197,7 @@ fn extract_switch(name: &str, tokens: &mut hir::TokensIterator<'_>, source: &Tex
} }
fn extract_mandatory( fn extract_mandatory(
config: &CommandConfig, config: &Signature,
name: &str, name: &str,
tokens: &mut hir::TokensIterator<'a>, tokens: &mut hir::TokensIterator<'a>,
source: &Text, source: &Text,

View File

@ -69,52 +69,76 @@ impl PositionalType {
} }
} }
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone, new)]
pub struct CommandConfig { pub struct Signature {
pub name: String, pub name: String,
#[new(default)]
pub positional: Vec<PositionalType>, pub positional: Vec<PositionalType>,
#[new(value = "false")]
pub rest_positional: bool, pub rest_positional: bool,
#[new(default)]
pub named: IndexMap<String, NamedType>, pub named: IndexMap<String, NamedType>,
#[new(value = "false")]
pub is_filter: bool, pub is_filter: bool,
pub is_sink: bool,
} }
impl CommandConfig { impl Signature {
pub fn new(name: impl Into<String>) -> CommandConfig { pub fn build(name: impl Into<String>) -> Signature {
CommandConfig { Signature::new(name.into())
name: name.into(),
positional: vec![],
rest_positional: false,
named: IndexMap::default(),
is_filter: false,
is_sink: false,
}
} }
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 self.positional
.push(PositionalType::Mandatory(name.into(), ty.into())); .push(PositionalType::Mandatory(name.into(), ty.into()));
self 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 self.positional
.push(PositionalType::Optional(name.into(), ty.into())); .push(PositionalType::Optional(name.into(), ty.into()));
self self
} }
pub fn named(mut self, name: impl Into<String>, ty: impl Into<NamedType>) -> CommandConfig { pub fn named(mut self, name: impl Into<String>, ty: impl Into<SyntaxType>) -> Signature {
self.named.insert(name.into(), ty.into()); self.named
.insert(name.into(), NamedType::Optional(ty.into()));
self 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.is_sink = true;
self 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)] #[derive(Debug, Default, new, Serialize, Deserialize)]
@ -245,7 +269,7 @@ impl Iterator for PositionalIter<'a> {
} }
} }
impl CommandConfig { impl Signature {
crate fn parse_args( crate fn parse_args(
&self, &self,
call: &Spanned<CallNode>, call: &Spanned<CallNode>,

View File

@ -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 serde::{Deserialize, Serialize};
use std::io; use std::io;
pub trait Plugin { pub trait Plugin {
fn config(&mut self) -> Result<CommandConfig, ShellError>; fn config(&mut self) -> Result<Signature, ShellError>;
#[allow(unused)] #[allow(unused)]
fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> {
Err(ShellError::string( Err(ShellError::string(

View File

@ -1,6 +1,6 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess, serve_plugin, CallInfo, Signature, Plugin, PositionalType, Primitive, ReturnSuccess,
ReturnValue, ShellError, Spanned, Value, ReturnValue, ShellError, Spanned, Value,
}; };
@ -40,8 +40,8 @@ impl Add {
} }
impl Plugin for Add { impl Plugin for Add {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(CommandConfig { Ok(Signature {
name: "add".to_string(), name: "add".to_string(),
positional: vec![ positional: vec![
PositionalType::mandatory_any("Field"), PositionalType::mandatory_any("Field"),

View File

@ -2,7 +2,7 @@
use crossterm::{cursor, terminal, Attribute, RawScreen}; use crossterm::{cursor, terminal, Attribute, RawScreen};
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, ShellError, SpanSource, Spanned, serve_plugin, CallInfo, Signature, NamedType, Plugin, ShellError, SpanSource, Spanned,
Value, Value,
}; };
use pretty_hex::*; use pretty_hex::*;
@ -16,10 +16,10 @@ impl BinaryView {
} }
impl Plugin for BinaryView { impl Plugin for BinaryView {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
let mut named = IndexMap::new(); let mut named = IndexMap::new();
named.insert("lores".to_string(), NamedType::Switch); named.insert("lores".to_string(), NamedType::Switch);
Ok(CommandConfig { Ok(Signature {
name: "binaryview".to_string(), name: "binaryview".to_string(),
positional: vec![], positional: vec![],
is_filter: false, is_filter: false,

View File

@ -1,6 +1,6 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess, serve_plugin, CallInfo, Signature, Plugin, PositionalType, Primitive, ReturnSuccess,
ReturnValue, ShellError, Spanned, Value, ReturnValue, ShellError, Spanned, Value,
}; };
@ -40,8 +40,8 @@ impl Edit {
} }
impl Plugin for Edit { impl Plugin for Edit {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(CommandConfig { Ok(Signature {
name: "edit".to_string(), name: "edit".to_string(),
positional: vec![ positional: vec![
PositionalType::mandatory_any("Field"), PositionalType::mandatory_any("Field"),

View File

@ -1,6 +1,6 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive, serve_plugin, CallInfo, Signature, NamedType, Plugin, PositionalType, Primitive,
ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value, ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value,
}; };
@ -84,13 +84,13 @@ impl Inc {
} }
impl Plugin for Inc { impl Plugin for Inc {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
let mut named = IndexMap::new(); let mut named = IndexMap::new();
named.insert("major".to_string(), NamedType::Switch); named.insert("major".to_string(), NamedType::Switch);
named.insert("minor".to_string(), NamedType::Switch); named.insert("minor".to_string(), NamedType::Switch);
named.insert("patch".to_string(), NamedType::Switch); named.insert("patch".to_string(), NamedType::Switch);
Ok(CommandConfig { Ok(Signature {
name: "inc".to_string(), name: "inc".to_string(),
positional: vec![PositionalType::optional_any("Field")], positional: vec![PositionalType::optional_any("Field")],
is_filter: true, is_filter: true,

View File

@ -1,6 +1,6 @@
use indexmap::IndexMap; use indexmap::IndexMap;
use nu::{ use nu::{
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, serve_plugin, CallInfo, Signature, Plugin, Primitive, ReturnSuccess, ReturnValue,
ShellError, Spanned, Value, ShellError, Spanned, Value,
}; };
@ -14,8 +14,8 @@ impl NewSkip {
} }
impl Plugin for NewSkip { impl Plugin for NewSkip {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(CommandConfig { Ok(Signature {
name: "skip".to_string(), name: "skip".to_string(),
positional: vec![], positional: vec![],
is_filter: true, is_filter: true,

View File

@ -1,6 +1,6 @@
use derive_new::new; use derive_new::new;
use indexmap::IndexMap; 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::item::StringItem;
use ptree::output::print_tree_with; use ptree::output::print_tree_with;
use ptree::print_config::PrintConfig; use ptree::print_config::PrintConfig;
@ -80,8 +80,8 @@ impl TreeView {
struct TreeViewer; struct TreeViewer;
impl Plugin for TreeViewer { impl Plugin for TreeViewer {
fn config(&mut self) -> Result<CommandConfig, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(CommandConfig { Ok(Signature {
name: "tree".to_string(), name: "tree".to_string(),
positional: vec![], positional: vec![],
is_filter: false, is_filter: false,

View File

@ -34,20 +34,23 @@ macro_rules! trace_stream {
crate use crate::cli::MaybeOwned; crate use crate::cli::MaybeOwned;
crate use crate::commands::command::{ 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::context::{CommandRegistry, Context};
crate use crate::env::host::handle_unexpected; crate use crate::env::host::handle_unexpected;
crate use crate::env::{Environment, Host}; crate use crate::env::{Environment, Host};
crate use crate::errors::ShellError; crate use crate::errors::ShellError;
crate use crate::object::base as value;
crate use crate::object::types::ExtractType; crate use crate::object::types::ExtractType;
crate use crate::object::{Primitive, Value}; 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::stream::{InputStream, OutputStream};
crate use crate::traits::{HasSpan, ToDebug}; crate use crate::traits::{HasSpan, ToDebug};
crate use crate::Text; crate use crate::Text;
crate use futures::stream::BoxStream; crate use futures::stream::BoxStream;
crate use futures::{FutureExt, Stream, StreamExt}; crate use futures::{FutureExt, Stream, StreamExt};
crate use serde::{Deserialize, Serialize};
crate use std::collections::VecDeque; crate use std::collections::VecDeque;
crate use std::future::Future; crate use std::future::Future;
crate use std::sync::{Arc, Mutex}; crate use std::sync::{Arc, Mutex};

View File

@ -46,12 +46,17 @@ pub struct OutputStream {
} }
impl OutputStream { impl OutputStream {
#[allow(unused)]
pub fn empty() -> OutputStream { pub fn empty() -> OutputStream {
let v: VecDeque<ReturnValue> = VecDeque::new(); let v: VecDeque<ReturnValue> = VecDeque::new();
v.into() 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 { pub fn from_input(input: impl Stream<Item = Spanned<Value>> + Send + 'static) -> OutputStream {
OutputStream { OutputStream {
values: input.map(ReturnSuccess::value).boxed(), values: input.map(ReturnSuccess::value).boxed(),

View File

@ -19,13 +19,18 @@ impl AbsolutePath {
} }
} }
impl Div<&str> for AbsolutePath { impl Div<&str> for &AbsolutePath {
type Output = AbsolutePath; type Output = AbsolutePath;
fn div(self, rhs: &str) -> Self::Output { fn div(self, rhs: &str) -> Self::Output {
AbsolutePath { let parts = rhs.split("/");
inner: self.inner.join(rhs), 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; type Output = RelativePath;
fn div(self, rhs: T) -> Self::Output { fn div(self, rhs: T) -> Self::Output {
RelativePath { let parts = rhs.as_ref().split("/");
inner: self.inner.join(rhs.as_ref()), let mut result = self.inner.clone();
}
for part in parts {
result = result.join(part);
}
RelativePath::new(result)
} }
} }

View File

@ -83,27 +83,32 @@ fn open_error_if_file_not_found() {
#[test] #[test]
fn save_can_write_out_csv() -> Result<(), std::io::Error> { 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!( 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(), 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); let actual = h::file_contents(&expected_file);
assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0")); assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0"));
drop(playground);
drop(tmp);
Ok(()) 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 (_playground, tmp, _) = h::setup_playground_for("remove_file")?;
let file = AbsolutePath::new(&tmp) / "rm_test.txt"; let file = &AbsolutePath::new(&tmp) / "rm_test.txt";
// let file = tmp.path().join("rm_test.txt");
h::create_file_at(&file)?; h::create_file_at(&file)?;

View File

@ -82,6 +82,8 @@ macro_rules! nu_error {
} }
pub fn setup_playground_for(topic: &str) -> Result<(TempDir, TempDir, String), std::io::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 home = TempDir::new("nuplayground")?;
let child = TempDir::new_in(home.path(), topic)?; let child = TempDir::new_in(home.path(), topic)?;
let relative = child 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 { 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(); let mut contents = String::new();
file.read_to_string(&mut contents) file.read_to_string(&mut contents)
.expect("can not read file"); .expect("can not read file");