Core app foundation/opt parsing
This commit is contained in:
commit
c9ae7be6d0
|
@ -0,0 +1,2 @@
|
|||
target/
|
||||
debug/
|
|
@ -0,0 +1,667 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "arkham"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"console",
|
||||
"criterion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57cdfa5d50aad6cb4d44dcab6101a7f79925bd59d82ca42f38a9856a28865374"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc80946b3480f421c2f17ed1cb841753a371c7c5104f51d507e13f532c856aa"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"regex",
|
||||
"terminal_size",
|
||||
"unicode-width",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"itertools 0.10.1",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-epoch",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"plotters-svg",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
|
||||
dependencies = [
|
||||
"half",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.126"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "arkham"
|
||||
version = "0.1.0"
|
||||
authors = ["Joe Bellus <joe@5sigma.io>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
# indicatif = "0.15.0"
|
||||
console = "0.14.0"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
||||
[[bench]]
|
||||
name = "arg_parsing"
|
||||
harness = false
|
|
@ -0,0 +1,42 @@
|
|||
use arkham::{App, Command, Opt, OptKind};
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
fn parse_args(c: &mut Criterion) {
|
||||
c.bench_function("parse_args", |b| {
|
||||
let args = vec![
|
||||
"--user".into(),
|
||||
"joe".into(),
|
||||
"--config".into(),
|
||||
"c.json".into(),
|
||||
"thing".into(),
|
||||
];
|
||||
let app = App::new()
|
||||
.opt(Opt {
|
||||
name: "user".into(),
|
||||
short: "u".into(),
|
||||
long: "user".into(),
|
||||
kind: OptKind::String,
|
||||
})
|
||||
.command(
|
||||
Command::new("thing")
|
||||
.opt(Opt {
|
||||
name: "config".into(),
|
||||
short: "c".into(),
|
||||
long: "config".into(),
|
||||
kind: OptKind::String,
|
||||
})
|
||||
.handler(|_, ctx, _| {
|
||||
assert_eq!(ctx.get_string("user"), Some("joe".into()));
|
||||
assert_eq!(ctx.get_string("config"), Some("c.json".into()));
|
||||
}),
|
||||
);
|
||||
|
||||
b.iter(|| {
|
||||
let _ = app.run_with(args.clone());
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, parse_args,);
|
||||
|
||||
criterion_main!(benches);
|
|
@ -0,0 +1,29 @@
|
|||
use arkham::{App, Context, Opt};
|
||||
|
||||
fn main() {
|
||||
let _ = App::new()
|
||||
.name("Fibonacci App")
|
||||
.version("1.0")
|
||||
.opt(Opt::scalar("count").short("n").long("num"))
|
||||
.handler(fibonacci_handler)
|
||||
.run()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn fibonacci_handler(_app: &App, ctx: &Context, _args: &[String]) {
|
||||
let v = fibonacci(
|
||||
ctx.get_string("count")
|
||||
.unwrap_or("1".to_string())
|
||||
.parse()
|
||||
.unwrap_or(1),
|
||||
);
|
||||
println!("Value is: {}", v);
|
||||
}
|
||||
|
||||
fn fibonacci(n: u32) -> u32 {
|
||||
match n {
|
||||
0 => 1,
|
||||
1 => 1,
|
||||
_ => fibonacci(n - 1) + fibonacci(n - 2),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// use arkham::TaskGroup;
|
||||
|
||||
fn main() {
|
||||
// let tasks = TaskGroup::new();
|
||||
// let task = tasks.start_task("task 1");
|
||||
// task.tick();
|
||||
// tasks.join();
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
use super::command::{help, Command, Handler};
|
||||
use super::context::Context;
|
||||
use super::opt::{ActiveOpt, Opt, OptError, OptKind};
|
||||
|
||||
use std::env;
|
||||
|
||||
type Result<T> = std::result::Result<T, OptError>;
|
||||
|
||||
pub struct App {
|
||||
name: Option<&'static str>,
|
||||
version: Option<&'static str>,
|
||||
pub root: Command,
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: None,
|
||||
version: None,
|
||||
root: Command::new("root"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn application_header(&self) -> String {
|
||||
format!(
|
||||
"{} - {}",
|
||||
self.name.as_ref().unwrap_or(&env!("CARGO_PKG_NAME")),
|
||||
self.version.as_ref().unwrap_or(&env!("CARGO_PKG_VERSION"))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
/// Contructs a new App instance which can have opts defined and subcommands attached.
|
||||
pub fn new() -> Self {
|
||||
App::default().command(Command::new("help").handler(help))
|
||||
}
|
||||
|
||||
/// Sets the name of the application. If not set the cargo package name will be used.
|
||||
///
|
||||
/// Exmaple:
|
||||
///
|
||||
/// ```rust
|
||||
/// use arkham::App;
|
||||
/// let app = App::new().name("new app");
|
||||
/// ```
|
||||
pub fn name(mut self, name: &'static str) -> Self {
|
||||
self.name = Some(name);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the version for the application. If not set the cargo package version is used.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use arkham::App;
|
||||
/// App::new().version("1.0.0");
|
||||
/// ```
|
||||
pub fn version(mut self, version: &'static str) -> Self {
|
||||
self.version = Some(version);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a root level command to the application. This command can then be executed with:
|
||||
///
|
||||
/// myapp command_name
|
||||
///
|
||||
/// Help flags will also be generated for the command which will display command
|
||||
/// information for:
|
||||
///
|
||||
/// myapp --help command_name or myapp help command_name
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{App, Command, Context};
|
||||
/// App::new().command(Command::new("subcommand").handler(my_handler));
|
||||
///
|
||||
/// fn my_handler(app: &App, ctx: &Context, args: &[String]) {}
|
||||
/// ```
|
||||
pub fn command(mut self, cmd: Command) -> Self {
|
||||
self.root.commands.push(cmd);
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds a root level opt/flag that is available to all commands. Opts are given a name which
|
||||
/// is used to reference them, as well as a short and long identifier.
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{App, Opt};
|
||||
/// App::new().opt(Opt::flag("verbose").short("v").long("verbose"));
|
||||
/// ```
|
||||
pub fn opt(mut self, opt: Opt) -> Self {
|
||||
self.root.opts.push(opt);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a handler function for the bare root command. If this is not set an error will be
|
||||
/// generated and a help message will be displayed indicating the available subcommands.
|
||||
/// The handler function takes an instance of the app, the context which contains the opts and
|
||||
/// flags, and any additionally passeed arguments.
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{App, Command, Context};
|
||||
/// App::new().handler(my_handler);
|
||||
///
|
||||
/// fn my_handler(app: &App, ctx: &Context, args: &[String]) {}
|
||||
/// ```
|
||||
pub fn handler(mut self, f: Handler) -> Self {
|
||||
self.root.handler = Some(f);
|
||||
self
|
||||
}
|
||||
|
||||
/// Execute the app and any specified handlers based on the passed arguemnts. This function is
|
||||
/// mostly used for testing or any situation where you need to pass arbitrary arguments instead
|
||||
/// of using the ones passed to the application.
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{App, Command, Context, Opt};
|
||||
/// App::new()
|
||||
/// .opt(Opt::flag("name").short("n").long("name"))
|
||||
/// .handler(my_handler)
|
||||
/// .run_with(vec!["-n".to_string(), "alice".to_string()]);
|
||||
///
|
||||
/// fn my_handler(app: &App, ctx: &Context, args: &[String]) {
|
||||
/// println!("Hello, {}", ctx.get_string("name").unwrap());
|
||||
/// }
|
||||
/// ```
|
||||
pub fn run_with(&self, args: Vec<String>) -> Result<()> {
|
||||
run_command(self, &self.root, &args, &mut vec![])
|
||||
}
|
||||
|
||||
/// Execute the app and any specified handlers based on the arguments passsed to the
|
||||
/// application.
|
||||
///
|
||||
/// Example:
|
||||
/// running with myapp --name alice
|
||||
/// ```rust
|
||||
/// use arkham::{App, Command, Context, Opt};
|
||||
/// App::new()
|
||||
/// .opt(Opt::flag("name").short("n").long("name"))
|
||||
/// .handler(my_handler)
|
||||
/// .run();
|
||||
///
|
||||
/// fn my_handler(app: &App, ctx: &Context, args: &[String]) {
|
||||
/// println!("Hello, {}", ctx.get_string("name").unwrap_or_else(|| "unnamed".into()));
|
||||
/// }
|
||||
/// ```
|
||||
pub fn run(&mut self) -> Result<()> {
|
||||
self.run_with(env::args().collect())
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the core logic for parsing arguments and executing handlers. It is ran but the App::run
|
||||
/// and App::run_with functions.
|
||||
fn run_command(app: &App, cmd: &Command, args: &[String], opts: &mut Vec<ActiveOpt>) -> Result<()> {
|
||||
// Get an iterator for the incomming arguments
|
||||
let mut args = args.iter();
|
||||
// We will keep track of any arguments that arent consumed by the current command.
|
||||
// These will be either used to collect arguments from subcommands or passed as additional args
|
||||
// to the command.
|
||||
let mut ignored: Vec<String> = vec![];
|
||||
// Loop through all passed in args
|
||||
while let Some(arg) = args.next() {
|
||||
// Check for long args
|
||||
if arg.starts_with("--") {
|
||||
if let Some(opt) = cmd.opts.iter().find(|o| &o.long == &arg[2..]) {
|
||||
match opt.kind {
|
||||
OptKind::Flag => {
|
||||
opts.push(ActiveOpt::new(opt.clone(), vec!["".into()]));
|
||||
}
|
||||
OptKind::String => {
|
||||
if let Some(value) = args.next() {
|
||||
opts.push(ActiveOpt::new(opt.clone(), vec![value.clone()]));
|
||||
} else {
|
||||
return Err(OptError::InvalidOpt(opt.name.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ignored.push(arg.clone());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Check for short args
|
||||
if arg.starts_with("-") {
|
||||
if let Some(opt) = cmd.opts.iter().find(|o| &o.short == &arg[1..]) {
|
||||
opts.push(ActiveOpt::new(opt.clone(), vec!["".into()]));
|
||||
} else {
|
||||
ignored.push(arg.clone());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ignored.push(arg.clone());
|
||||
}
|
||||
|
||||
// Find an recurse into sub commands if the remaining argumetns match any subcommand name
|
||||
if let Some(cmd) = cmd
|
||||
.commands
|
||||
.iter()
|
||||
.find(|cmd| ignored.iter().any(|a| *a == cmd.name))
|
||||
{
|
||||
ignored.retain(|a| *a != cmd.name);
|
||||
return run_command(app, cmd, &ignored, opts);
|
||||
}
|
||||
|
||||
// If any ignored parameters start with "-" we will throw an unknwon flag error.
|
||||
if let Some(arg) = ignored.iter().find(|a| a.starts_with("-")) {
|
||||
return Err(OptError::InvalidOpt(arg.clone()));
|
||||
}
|
||||
|
||||
// Execute the command handler
|
||||
if let Some(handler) = cmd.handler {
|
||||
handler(app, &Context::new(opts.clone()), &ignored);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::App;
|
||||
#[test]
|
||||
fn test_long_string() {
|
||||
let args: Vec<String> = vec!["--user".into(), "joe".into()];
|
||||
let app = App::new()
|
||||
.opt(Opt::scalar("user").short("u").long("user"))
|
||||
.handler(|_, ctx, _| {
|
||||
assert_eq!(ctx.get_string("user"), Some("joe".into()));
|
||||
});
|
||||
|
||||
let res = app.run_with(args);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_subcommand() {
|
||||
let args = vec![
|
||||
"--user".into(),
|
||||
"joe".into(),
|
||||
"--config".into(),
|
||||
"c.json".into(),
|
||||
"thing".into(),
|
||||
];
|
||||
let app = App::new()
|
||||
.opt(Opt::scalar("user").short("u").long("user"))
|
||||
.command(
|
||||
Command::new("thing")
|
||||
.opt(Opt::scalar("config").short("c").long("config"))
|
||||
.handler(|_, ctx, _| {
|
||||
assert_eq!(ctx.get_string("user"), Some("joe".into()));
|
||||
assert_eq!(ctx.get_string("config"), Some("c.json".into()));
|
||||
}),
|
||||
);
|
||||
let res = app.run_with(args);
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
fn function_handler(_app: &App, _ctx: &Context, _args: &[String]) {
|
||||
assert!(true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_function_handler() {
|
||||
App::new().handler(function_handler);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extra_args() {
|
||||
let args = vec!["somefile".to_string()];
|
||||
App::new()
|
||||
.handler(|_, _, args| {
|
||||
assert_eq!(args.len(), 1);
|
||||
assert_eq!(args.first(), Some(&"somefile".to_string()));
|
||||
})
|
||||
.run_with(args)
|
||||
.expect("app error");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_flag() {
|
||||
App::new()
|
||||
.opt(Opt::flag("verbose").short("v").long("verbose"))
|
||||
.handler(|_, ctx, _| {
|
||||
assert_eq!(ctx.flag("verbose"), true);
|
||||
})
|
||||
.run_with(vec!["-v".into()])
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_long_flag() {
|
||||
let r = App::new()
|
||||
.opt(Opt::flag("verbose").short("v").long("verbose"))
|
||||
.run_with(vec!["--user".into()]);
|
||||
assert!(r.is_err(), "Should error for invalid long flag");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_short_flag() {
|
||||
let r = App::new()
|
||||
.opt(Opt::flag("verbose").short("v").long("verbose"))
|
||||
.run_with(vec!["-u".into()]);
|
||||
assert!(r.is_err(), "Should error for invalid short flag");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
use crate::{
|
||||
context::Context,
|
||||
opt::{self, Opt},
|
||||
vox, App,
|
||||
};
|
||||
|
||||
pub type Handler = fn(&App, &Context, &[String]);
|
||||
|
||||
pub struct Command {
|
||||
pub name: String,
|
||||
pub commands: Vec<Command>,
|
||||
pub handler: Option<Handler>,
|
||||
pub opts: Vec<opt::Opt>,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
pub fn new<T: Into<String>>(name: T) -> Self {
|
||||
Command {
|
||||
name: name.into(),
|
||||
commands: vec![],
|
||||
handler: None,
|
||||
opts: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handler(mut self, f: Handler) -> Self {
|
||||
self.handler = Some(f);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn opt(mut self, opt: Opt) -> Self {
|
||||
self.opts.push(opt);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn help(app: &App, _ctx: &Context, _args: &[String]) {
|
||||
vox::print(app.application_header());
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
use crate::opt::{ActiveOpt, OptKind};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Context {
|
||||
opts: Vec<ActiveOpt>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub(crate) fn new(opts: Vec<ActiveOpt>) -> Self {
|
||||
Self { opts }
|
||||
}
|
||||
|
||||
pub fn flag(&self, name: &str) -> bool {
|
||||
self.opts
|
||||
.iter()
|
||||
.any(|o| o.definition.name == name && matches!(o.definition.kind, OptKind::Flag))
|
||||
}
|
||||
|
||||
pub fn get_string(&self, name: &str) -> Option<String> {
|
||||
self.opts
|
||||
.iter()
|
||||
.find_map(|o| {
|
||||
if o.definition.name == name {
|
||||
Some(o.raw_value.first().cloned())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
mod app;
|
||||
mod command;
|
||||
mod context;
|
||||
mod opt;
|
||||
// mod style;
|
||||
// mod tasks;
|
||||
pub mod vox;
|
||||
pub use app::*;
|
||||
pub use command::*;
|
||||
pub use context::*;
|
||||
pub use opt::*;
|
||||
// pub use style::*;
|
|
@ -0,0 +1,91 @@
|
|||
#[derive(Debug)]
|
||||
pub enum OptError {
|
||||
InvalidOpt(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Opt {
|
||||
pub name: String,
|
||||
pub short: String,
|
||||
pub long: String,
|
||||
pub(crate) kind: OptKind,
|
||||
}
|
||||
|
||||
impl Opt {
|
||||
/// Create a boolean opt that is present or not and does not accept additional arguments
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{Opt, App};
|
||||
/// App::new().opt(Opt::flag("verbose").short("v").long("verbose"));
|
||||
///```
|
||||
pub fn flag(name: &str) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
short: "".into(),
|
||||
long: "".into(),
|
||||
kind: OptKind::Flag,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a opt that accepts additioanl arguments
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{Opt, App};
|
||||
/// App::new().opt(Opt::scalar("user").short("u").long("user"));
|
||||
///```
|
||||
pub fn scalar(name: &str) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
short: "".into(),
|
||||
long: "".into(),
|
||||
kind: OptKind::String,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the short flag that can be used with -x
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{Opt, App};
|
||||
/// App::new().opt(Opt::scalar("user").short("u").long("user"));
|
||||
///```
|
||||
pub fn short(mut self, short: &str) -> Self {
|
||||
self.short = short.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the long flag that can be used with --xxxxx
|
||||
///
|
||||
/// Example:
|
||||
/// ```rust
|
||||
/// use arkham::{Opt, App};
|
||||
/// App::new().opt(Opt::scalar("user").short("u").long("user"));
|
||||
///```
|
||||
pub fn long(mut self, long: &str) -> Self {
|
||||
self.long = long.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum OptKind {
|
||||
Flag,
|
||||
String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct ActiveOpt {
|
||||
pub definition: Opt,
|
||||
pub raw_value: Vec<String>,
|
||||
}
|
||||
|
||||
impl ActiveOpt {
|
||||
pub fn new(definition: Opt, raw_value: Vec<String>) -> Self {
|
||||
ActiveOpt {
|
||||
definition,
|
||||
raw_value,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
use console::style;
|
||||
use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressStyle};
|
||||
use std::{
|
||||
sync::{Arc, Mutex},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TaskGroup {
|
||||
mp: Arc<MultiProgress>,
|
||||
}
|
||||
|
||||
impl TaskGroup {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
mp: Arc::new(MultiProgress::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_task(&self, desc: &str) -> Task {
|
||||
let pb = self.mp.add(ProgressBar::new(1));
|
||||
let spinner_style = ProgressStyle::default_spinner()
|
||||
.tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ")
|
||||
.template("{prefix:.bold.dim} {spinner} {wide_msg}");
|
||||
pb.set_style(spinner_style);
|
||||
Task::new(TaskState {
|
||||
pb,
|
||||
desc: desc.into(),
|
||||
started_at: Instant::now(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn join(&self) {
|
||||
self.mp.join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Task(Arc<Mutex<TaskState>>);
|
||||
|
||||
impl Task {
|
||||
pub fn new(state: TaskState) -> Self {
|
||||
Self(Arc::new(Mutex::new(state)))
|
||||
}
|
||||
|
||||
pub fn tick(&self) {
|
||||
let state = self.0.lock().unwrap();
|
||||
state.pb.set_message(&format!(
|
||||
"{} [{}]",
|
||||
state.desc,
|
||||
style(HumanDuration(state.started_at.elapsed())).yellow()
|
||||
));
|
||||
state.pb.tick();
|
||||
}
|
||||
|
||||
pub fn complete(&self) {
|
||||
self.0.lock().unwrap().pb.finish_with_message("OK");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TaskState {
|
||||
pb: ProgressBar,
|
||||
desc: String,
|
||||
started_at: Instant,
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
use console::style;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub fn message<T: Display>(str: T) {
|
||||
println!("{}", style(str).white().bold());
|
||||
}
|
||||
|
||||
pub fn header<T: Display>(str: T) {
|
||||
println!(
|
||||
"{} {} {}",
|
||||
style("-=[").red().dim(),
|
||||
style(str).white().bold(),
|
||||
style("]=-").red().dim()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn note<T: Display>(str: T) {
|
||||
println!("{}", style(str).white().dim());
|
||||
}
|
||||
|
||||
pub fn description_list(list: HashMap<String, String>) {
|
||||
let max_length = list.keys().map(|v| v.len()).max().unwrap_or(10) + 3;
|
||||
for (name, desc) in list {
|
||||
let spaced_name = format!("{:width$}", name, width = max_length);
|
||||
println!("{}{}", style(spaced_name).bold(), style(desc).dim())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print<T: Display>(s: T) {
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {}
|
Loading…
Reference in New Issue