Merge pull request #90 from jonathandturner/sinks

Add sink-style commands
This commit is contained in:
Jonathan Turner 2019-06-07 19:58:25 +12:00 committed by GitHub
commit 0b71d8b034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 464 additions and 108 deletions

125
Cargo.lock generated
View File

@ -254,6 +254,21 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "config"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "console"
version = "0.7.5"
@ -771,6 +786,11 @@ dependencies = [
"synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fixedbitset"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "flate2"
version = "1.0.7"
@ -951,6 +971,17 @@ name = "is-match"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "isatty"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.7.11"
@ -1216,6 +1247,15 @@ name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "nom"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nom"
version = "5.0.0-beta1"
@ -1266,6 +1306,7 @@ dependencies = [
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ptree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustyline 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1412,6 +1453,11 @@ dependencies = [
"num-traits 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ordermap"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "output_vt100"
version = "0.1.2"
@ -1487,6 +1533,15 @@ name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "petgraph"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pin-utils"
version = "0.1.0-alpha.4"
@ -1572,6 +1627,22 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ptree"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
"directories 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
"serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
"tint 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quick-error"
version = "1.2.2"
@ -1764,6 +1835,11 @@ dependencies = [
"termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust-ini"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-demangle"
version = "0.1.14"
@ -1857,6 +1933,18 @@ name = "serde"
version = "1.0.91"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde-hjson"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde-hjson"
version = "0.9.0"
@ -1869,6 +1957,15 @@ dependencies = [
"serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde-value"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.91"
@ -2124,6 +2221,14 @@ dependencies = [
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tint"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-executor"
version = "0.1.7"
@ -2169,6 +2274,14 @@ dependencies = [
"tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.5.1"
@ -2404,6 +2517,7 @@ dependencies = [
"checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum conch-parser 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "baf61cea7edff80a7d8a9a4c219d391664715559e9d4e7129494b45278705a41"
"checksum config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9107d78ed62b3fa5a86e7d18e647abed48cfd8f8fab6c72f4cdb982d196f7e6"
"checksum console 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf3720d3f3fc30b721ef1ae54e13af3264af4af39dc476a8de56a6ee1e2184b"
"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum content_inspector 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b7bda66e858c683005a53a9a60c69a4aca7eeaa45d124526e389f7aec8e62f38"
@ -2459,6 +2573,7 @@ dependencies = [
"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
"checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
"checksum flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f87e68aa82b2de08a6e037f1385455759df6e445a8df5e005b4297191dbf18aa"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
@ -2480,6 +2595,7 @@ dependencies = [
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
"checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
"checksum isatty 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e31a8281fc93ec9693494da65fbf28c0c2aa60a2eaec25dc58e2f31952e95edc"
"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
@ -2512,6 +2628,7 @@ dependencies = [
"checksum nix 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46f0f3210768d796e8fa79ec70ee6af172dacbe7147f5e69be5240a47778302b"
"checksum nix 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d10caafde29a846a82ae0af70414e4643e072993441033b2c93217957e2f867"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
"checksum nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)" = "6527f311b2baba609e980e008460ab5ebff6d6da15213bb8eb193b7746eefa24"
"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db"
"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8"
@ -2528,6 +2645,7 @@ dependencies = [
"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
"checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc"
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
"checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
"checksum output_vt100 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
"checksum pancurses 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3058bc37c433096b2ac7afef1c5cdfae49ede0a4ffec3dfc1df1df0959d0ff0"
@ -2536,6 +2654,7 @@ dependencies = [
"checksum parse-zoneinfo 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "089a398ccdcdd77b8c38909d5a1e4b67da1bc4c9dbfe6d5b536c828eddb779e5"
"checksum pdcurses-sys 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "084dd22796ff60f1225d4eb6329f33afaf4c85419d51d440ab6b8c6f4529166b"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum plist 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f4739851c08dd9a62a78beff2edf1a438517268b2c563c42fc6d9d3139e42d2a"
@ -2544,6 +2663,7 @@ dependencies = [
"checksum prettyprint 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2705417f8aa07cb6308db42e55623479c1c9667942a4d5e4174c684e5da5590d"
"checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum ptree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0a3be00b19ee7bd33238c1c523a7ab4df697345f6b36f90827a7860ea938d4"
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@ -2565,6 +2685,7 @@ dependencies = [
"checksum regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f0a0bcab2fd7d1d7c54fa9eae6f43eddeb9ce2e7352f8518a814a4f65d60c58"
"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96"
"checksum render-tree 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68ed587df09cfb7ce1bc6fe8f77e24db219f222c049326ccbfb948ec67e31664"
"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
"checksum rustc-demangle 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "ccc78bfd5acd7bf3e89cffcf899e5cb1a52d6fafa8dec2739ad70c9577a57288"
"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
@ -2579,7 +2700,9 @@ dependencies = [
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
"checksum serde 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "a72e9b96fa45ce22a4bc23da3858dfccfd60acd28a25bcd328a98fdd6bea43fd"
"checksum serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153"
"checksum serde-hjson 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4640cf3168e40c00c874ff1ad436c0f18c37edec101d5d897a4396f617abce29"
"checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f"
"checksum serde_derive 1.0.91 (registry+https://github.com/rust-lang/crates.io-index)" = "101b495b109a3e3ca8c4cbe44cf62391527cdfb6ba15821c5ce80bcd5ea23f9f"
"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d"
"checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5"
@ -2609,10 +2732,12 @@ dependencies = [
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
"checksum tint 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7af24570664a3074673dbbf69a65bdae0ae0b72f2949b1adfbacb736ee4d6896"
"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af"
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
"checksum tokio-threadpool 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72558af20be886ea124595ea0f806dd5703b8958e4705429dd58b3d8231f72f2"
"checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
"checksum toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039"
"checksum toml-query 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a24369a1894ac8224efcfd567c3d141aea360292f49888e7ec7dcc316527aebb"
"checksum toml-query_derive 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335"

View File

@ -56,6 +56,7 @@ lazy_static = "1.3.0"
git2 = "0.8.0"
dirs = "2.0.1"
ctrlc = "3.1.3"
ptree = "0.2"
[dependencies.pancurses]
version = "0.16"

View File

@ -1,3 +1,7 @@
use crate::commands::classified::SinkCommand;
use crate::commands::command::sink;
use crate::commands::{autoview, tree};
use crate::prelude::*;
use crate::commands::classified::{
@ -7,17 +11,16 @@ use crate::commands::classified::{
use crate::context::Context;
crate use crate::errors::ShellError;
use crate::evaluate::Scope;
crate use crate::format::{EntriesListView, GenericView};
use crate::git::current_branch;
use crate::object::Value;
use crate::parser::ast::{Expression, Leaf, RawExpression};
use crate::parser::{Args, Pipeline};
use crate::stream::empty_stream;
use log::debug;
use rustyline::error::ReadlineError;
use rustyline::{self, ColorMode, Config, Editor};
use std::collections::VecDeque;
use std::error::Error;
use std::iter::Iterator;
use std::sync::atomic::{AtomicBool, Ordering};
@ -44,7 +47,6 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
use crate::commands::*;
context.add_commands(vec![
command("format-list", format_list),
command("ps", ps::ps),
command("ls", ls::ls),
command("cd", cd::cd),
@ -69,6 +71,11 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
Arc::new(Config),
command("sort-by", sort_by::sort_by),
]);
context.add_sinks(vec![
sink("autoview", autoview::autoview),
sink("tree", tree::tree),
]);
}
let config = Config::builder().color_mode(ColorMode::Forced).build();
@ -212,7 +219,19 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
debug!("=== Parsed ===");
debug!("{:#?}", result);
let pipeline = classify_pipeline(&result, ctx)?;
let mut pipeline = classify_pipeline(&result, ctx)?;
match pipeline.commands.last() {
Some(ClassifiedCommand::Sink(_)) => {}
Some(ClassifiedCommand::External(_)) => {}
_ => pipeline.commands.push(ClassifiedCommand::Sink(SinkCommand {
command: sink("autoview", autoview::autoview),
args: Args {
positional: vec![],
named: indexmap::IndexMap::new(),
},
})),
}
let mut input = ClassifiedInputStream::new();
@ -237,9 +256,30 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
))
}
(Some(ClassifiedCommand::Sink(_)), Some(_)) => {
return LineResult::Error(ShellError::string("Commands like table, save, and autoview must come last in the pipeline"))
}
(Some(ClassifiedCommand::Sink(left)), None) => {
let input_vec: Vec<Value> = input.objects.collect().await;
left.run(
ctx,
input_vec,
)?;
break;
}
(
Some(ClassifiedCommand::Internal(left)),
Some(ClassifiedCommand::Internal(_)),
Some(ClassifiedCommand::External(_)),
) => match left.run(ctx, input).await {
Ok(val) => ClassifiedInputStream::from_input_stream(val),
Err(err) => return LineResult::Error(err),
},
(
Some(ClassifiedCommand::Internal(left)),
Some(_),
) => match left.run(ctx, input).await {
Ok(val) => ClassifiedInputStream::from_input_stream(val),
Err(err) => return LineResult::Error(err),
@ -260,17 +300,9 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
Err(err) => return LineResult::Error(err),
},
(
Some(ClassifiedCommand::Internal(left)),
Some(ClassifiedCommand::External(_)),
) => match left.run(ctx, input).await {
Ok(val) => ClassifiedInputStream::from_input_stream(val),
Err(err) => return LineResult::Error(err),
},
(
Some(ClassifiedCommand::External(left)),
Some(ClassifiedCommand::Internal(_)),
Some(_),
) => match left.run(ctx, input, StreamNext::Internal).await {
Ok(val) => val,
Err(err) => return LineResult::Error(err),
@ -285,21 +317,6 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
}
}
let input_vec: VecDeque<_> = input.objects.collect().await;
if input_vec.len() > 0 {
if equal_shapes(&input_vec) {
let array = crate::commands::stream_to_array(input_vec.boxed()).await;
let args = CommandArgs::from_context(ctx, vec![], array);
let mut result = format(args);
let mut vec = vec![];
vec.send_all(&mut result).await?;
} else {
let args = CommandArgs::from_context(ctx, vec![], input_vec.boxed());
format(args).collect::<Vec<_>>().await;
}
}
LineResult::Success(line.to_string())
}
Err(ReadlineError::Interrupted) => LineResult::Error(ShellError::string("CTRL-C")),
@ -365,17 +382,31 @@ fn classify_command(
args,
}))
}
false => {
let arg_list_strings: Vec<String> = match args {
Some(args) => args.iter().map(|i| i.as_external_arg()).collect(),
None => vec![],
};
false => match context.has_sink(&name.to_string()) {
true => {
let command = context.get_sink(&name.to_string());
let config = command.config();
let scope = Scope::empty();
Ok(ClassifiedCommand::External(ExternalCommand {
name: name.to_string(),
args: arg_list_strings,
}))
}
let args = match args {
Some(args) => config.evaluate_args(args.iter(), &scope)?,
None => Args::default(),
};
Ok(ClassifiedCommand::Sink(SinkCommand { command, args }))
}
false => {
let arg_list_strings: Vec<String> = match args {
Some(args) => args.iter().map(|i| i.as_external_arg()).collect(),
None => vec![],
};
Ok(ClassifiedCommand::External(ExternalCommand {
name: name.to_string(),
args: arg_list_strings,
}))
}
},
},
(_, None) => Err(ShellError::string(
@ -390,64 +421,3 @@ fn classify_command(
)))
}
}
crate fn format(args: CommandArgs) -> OutputStream {
let host = args.host.clone();
let input = args.input.map(|a| a.copy());
let input = input.collect::<Vec<_>>();
input
.then(move |input| {
let last = input.len() - 1;
let mut host = host.lock().unwrap();
for (i, item) in input.iter().enumerate() {
let view = GenericView::new(item);
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
if last != i {
host.stdout("");
}
}
futures::future::ready(empty_stream())
})
.flatten_stream()
.boxed()
}
crate fn format_list(args: CommandArgs) -> Result<OutputStream, ShellError> {
let host = args.host.clone();
let view = EntriesListView::from_stream(args.input);
Ok(view
.then(move |view| {
handle_unexpected(&mut *host.lock().unwrap(), |host| {
crate::format::print_view(&view, host)
});
futures::future::ready(empty_stream())
})
.flatten_stream()
.boxed())
}
fn equal_shapes(input: &VecDeque<Value>) -> bool {
let mut items = input.iter();
let item = match items.next() {
Some(item) => item,
None => return false,
};
let desc = item.data_descriptors();
for item in items {
if desc != item.data_descriptors() {
return false;
}
}
true
}

View File

@ -1,4 +1,5 @@
crate mod args;
crate mod autoview;
crate mod cd;
crate mod classified;
crate mod command;
@ -21,11 +22,12 @@ crate mod split_row;
crate mod to_array;
crate mod to_json;
crate mod to_toml;
crate mod tree;
crate mod trim;
crate mod view;
crate mod where_;
crate use command::command;
crate use config::Config;
crate use to_array::stream_to_array;
crate use where_::Where;

43
src/commands/autoview.rs Normal file
View File

@ -0,0 +1,43 @@
use crate::commands::command::SinkCommandArgs;
use crate::errors::ShellError;
use crate::format::{GenericView, TableView};
use crate::prelude::*;
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
if args.input.len() > 0 {
if equal_shapes(&args.input) {
let mut host = args.ctx.host.lock().unwrap();
let view = TableView::from_list(&args.input).unwrap();
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
} else {
let mut host = args.ctx.host.lock().unwrap();
for i in args.input.iter() {
let view = GenericView::new(&i);
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
host.stdout("");
}
}
}
Ok(())
}
fn equal_shapes(input: &Vec<Value>) -> bool {
let mut items = input.iter();
let item = match items.next() {
Some(item) => item,
None => return false,
};
let desc = item.data_descriptors();
for item in items {
if desc != item.data_descriptors() {
return false;
}
}
true
}

View File

@ -1,3 +1,4 @@
use crate::commands::command::Sink;
use crate::parser::ast::Expression;
use crate::parser::registry::Args;
use crate::prelude::*;
@ -79,9 +80,21 @@ crate enum ClassifiedCommand {
#[allow(unused)]
Expr(Expression),
Internal(InternalCommand),
Sink(SinkCommand),
External(ExternalCommand),
}
crate struct SinkCommand {
crate command: Arc<dyn Sink>,
crate args: Args,
}
impl SinkCommand {
crate fn run(self, context: &mut Context, input: Vec<Value>) -> Result<(), ShellError> {
context.run_sink(self.command, self.args, input)
}
}
crate struct InternalCommand {
crate command: Arc<dyn Command>,
crate args: Args,

View File

@ -2,6 +2,7 @@ use crate::errors::ShellError;
use crate::object::Value;
use crate::parser::CommandConfig;
use crate::prelude::*;
use core::future::Future;
use std::path::PathBuf;
pub struct CommandArgs {
@ -28,6 +29,28 @@ impl CommandArgs {
}
}
pub struct SinkCommandArgs {
pub ctx: Context,
pub positional: Vec<Value>,
pub named: indexmap::IndexMap<String, Value>,
pub input: Vec<Value>,
}
impl SinkCommandArgs {
crate fn from_context(
ctx: &'caller mut Context,
positional: Vec<Value>,
input: Vec<Value>,
) -> SinkCommandArgs {
SinkCommandArgs {
ctx: ctx.clone(),
positional,
named: indexmap::IndexMap::default(),
input,
}
}
}
#[derive(Debug)]
pub enum CommandAction {
ChangeCwd(PathBuf),
@ -60,6 +83,21 @@ pub trait Command {
}
}
pub trait Sink {
fn run(&self, args: SinkCommandArgs) -> Result<(), ShellError>;
fn name(&self) -> &str;
fn config(&self) -> CommandConfig {
CommandConfig {
name: self.name().to_string(),
mandatory_positional: vec![],
optional_positional: vec![],
rest_positional: true,
named: indexmap::IndexMap::new(),
}
}
}
pub struct FnCommand {
name: String,
func: fn(CommandArgs) -> Result<OutputStream, ShellError>,
@ -84,3 +122,25 @@ pub fn command(
func,
})
}
pub struct FnSink {
name: String,
func: 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: fn(SinkCommandArgs) -> Result<(), ShellError>) -> Arc<dyn Sink> {
Arc::new(FnSink {
name: name.to_string(),
func,
})
}

View File

@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::{EntriesListView, GenericView};
use crate::{EntriesListView, GenericView, TreeView};
use futures::stream::{self, StreamExt};
use std::sync::{Arc, Mutex};

17
src/commands/tree.rs Normal file
View File

@ -0,0 +1,17 @@
use crate::commands::command::SinkCommandArgs;
use crate::errors::ShellError;
use crate::format::TreeView;
use crate::prelude::*;
pub fn tree(args: SinkCommandArgs) -> Result<(), ShellError> {
if args.input.len() > 0 {
let mut host = args.ctx.host.lock().unwrap();
for i in args.input.iter() {
let view = TreeView::from_value(&i);
handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
host.stdout("");
}
}
Ok(())
}

View File

@ -1,3 +1,5 @@
use crate::commands::command::Sink;
use crate::commands::command::SinkCommandArgs;
use crate::parser::Args;
use crate::prelude::*;
@ -5,8 +7,10 @@ use indexmap::IndexMap;
use std::error::Error;
use std::sync::Arc;
#[derive(Clone)]
pub struct Context {
commands: IndexMap<String, Arc<dyn Command>>,
sinks: IndexMap<String, Arc<dyn Sink>>,
crate host: Arc<Mutex<dyn Host + Send>>,
crate env: Arc<Mutex<Environment>>,
}
@ -15,6 +19,7 @@ impl Context {
crate fn basic() -> Result<Context, Box<dyn Error>> {
Ok(Context {
commands: indexmap::IndexMap::new(),
sinks: indexmap::IndexMap::new(),
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
env: Arc::new(Mutex::new(Environment::basic()?)),
})
@ -26,6 +31,40 @@ impl Context {
}
}
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 clone_sinks(&self) -> indexmap::IndexMap<String, Arc<dyn Sink>> {
self.sinks.clone()
}
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>,
args: Args,
input: Vec<Value>,
) -> Result<(), ShellError> {
let command_args = SinkCommandArgs {
ctx: self.clone(),
positional: args.positional,
named: args.named,
input,
};
command.run(command_args)
}
pub fn clone_commands(&self) -> indexmap::IndexMap<String, Arc<dyn Command>> {
self.commands.clone()
}

View File

@ -2,12 +2,15 @@ crate mod entries;
crate mod generic;
crate mod list;
crate mod table;
crate mod tree;
use crate::prelude::*;
crate use entries::{EntriesListView, EntriesView};
crate use generic::GenericView;
crate use list::ListView;
crate use table::TableView;
crate use tree::TreeView;
crate trait RenderView {
fn render_view(&self, host: &mut dyn Host) -> Result<(), ShellError>;

View File

@ -1,4 +1,4 @@
use crate::format::{EntriesView, RenderView, TableView};
use crate::format::{EntriesView, ListView, RenderView, TableView, TreeView};
use crate::object::Value;
use crate::prelude::*;
use derive_new::new;

83
src/format/tree.rs Normal file
View File

@ -0,0 +1,83 @@
use crate::format::RenderView;
use crate::prelude::*;
use derive_new::new;
use ptree::item::StringItem;
use ptree::output::print_tree_with;
use ptree::print_config::PrintConfig;
use ptree::style::{Color, Style};
use ptree::TreeBuilder;
// An entries list is printed like this:
//
// name : ...
// name2 : ...
// another_name : ...
#[derive(new)]
pub struct TreeView {
//entries: Vec<(crate::object::DescriptorName, Value)>,
tree: StringItem,
}
impl TreeView {
fn from_value_helper(value: &Value, mut builder: &mut TreeBuilder) {
match value {
Value::Primitive(p) => builder = builder.add_empty_child(p.format(None)),
Value::Object(o) => {
for (k, v) in o.entries.iter() {
builder = builder.begin_child(k.name.display().to_string());
Self::from_value_helper(v, builder);
builder = builder.end_child();
}
}
Value::List(l) => {
for elem in l.iter() {
Self::from_value_helper(elem, builder);
}
}
Value::Block(_) => {}
Value::Error(_) => {}
}
}
crate fn from_value(value: &Value) -> TreeView {
let descs = value.data_descriptors();
let mut tree = TreeBuilder::new("".to_string());
let mut builder = &mut tree;
for desc in descs {
let value = value.get_data(&desc);
builder = builder.begin_child(desc.name.display().to_string());
Self::from_value_helper(value.borrow(), &mut builder);
builder = builder.end_child();
//entries.push((desc.name.clone(), value.borrow().copy()))
}
TreeView::new(builder.build())
}
}
impl RenderView for TreeView {
fn render_view(&self, _host: &mut dyn Host) -> Result<(), ShellError> {
// Set up the print configuration
let config = {
let mut config = PrintConfig::from_env();
config.branch = Style {
foreground: Some(Color::Green),
dimmed: true,
..Style::default()
};
config.leaf = Style {
bold: true,
..Style::default()
};
//config.characters = UTF_CHARS_BOLD.into();
config.indent = 4;
config
};
// Print out the tree using custom formatting
print_tree_with(&self.tree, &config)?;
Ok(())
}
}

View File

@ -4,13 +4,13 @@ use crate::object::DataDescriptor;
use crate::object::{Primitive, Value};
use derive_new::new;
use indexmap::IndexMap;
use serde::ser::{Serialize, SerializeMap, Serializer};
use serde_derive::Deserialize;
use serde::ser::{Serialize, Serializer, SerializeMap};
use std::cmp::{Ordering, PartialOrd};
#[derive(Debug, Default, Eq, PartialEq, Deserialize, Clone, new)]
pub struct Dictionary {
entries: IndexMap<DataDescriptor, Value>,
pub entries: IndexMap<DataDescriptor, Value>,
}
impl PartialOrd for Dictionary {
@ -28,8 +28,8 @@ impl Serialize for Dictionary {
let mut map = serializer.serialize_map(Some(self.entries.len()))?;
for (k, v) in self.entries.iter() {
match v {
Value::Object(_) => {},
_ => map.serialize_entry(k, v)?
Value::Object(_) => {}
_ => map.serialize_entry(k, v)?,
}
}
for (k, v) in self.entries.iter() {