diff options
47 files changed, 0 insertions, 6087 deletions
diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 214b78f62542..000000000000 --- a/Cargo.lock +++ /dev/null @@ -1,1450 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "adler32" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "aho-corasick" -version = "0.7.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)", -] - -[[package]] -name = "alga" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "antidote" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "approx" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arc-swap" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "argon2rs" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", - "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "arrayvec" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "atty" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "autocfg" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "backtrace" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit-set" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bit-vec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "bitflags" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "blake2-rfc" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bstr" -version = "0.2.1" -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)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-automata 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "build_const" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "c2-chacha" -version = "0.2.2" -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)", - "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cc" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chrono" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "clap" -version = "2.33.0" -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)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (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.92 (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 = "constant_time_eq" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "crc" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crc32fast" -version = "1.2.0" -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)", -] - -[[package]] -name = "csv" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bstr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "csv-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "downcast-rs" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "dtoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "either" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "encode_unicode" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "failure" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.5" -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.35 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "flate2" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "futures" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "getrandom" -version = "0.1.6" -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)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "glob" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "humantime" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "include_dir" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "include_dir_impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "include_dir_impl" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itertools" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lexical-core" -version = "0.4.2" -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)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "libc" -version = "0.2.58" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libm" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "linked-hash-map" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.4.6" -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)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log-mdc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log4rs" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (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.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", - "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "maplit" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz-sys" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz_oxide" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "miniz_oxide_c_api" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lexical-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "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 = "num-complex" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ordered-float" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "prettytable-rs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proc-macro-hack-impl" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proptest" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "proptest-derive" -version = "0.1.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.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quote" -version = "0.6.12" -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)", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_chacha" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rand_core" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_pcg" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_users" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-automata" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.7 (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.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rusty-fork" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)", - "wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ryu" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ryu" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "scoped_threadpool" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "1.0.92" -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.7 (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-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.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_derive" -version = "1.0.92" -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.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_json" -version = "1.0.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_test" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "serde_yaml" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (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 = "spin" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "stackvector" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "static_assertions" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "syn" -version = "0.14.9" -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)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.15.35" -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)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.10.2" -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.35 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tempfile" -version = "3.0.8" -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.58 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "term" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread-id" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (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 = "thread_local" -version = "0.3.6" -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)", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (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 = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "toml" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "traitobject" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typemap" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-width" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unsafe-any" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "utf8-ranges" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vec_map" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "xanthous" -version = "0.1.0" -dependencies = [ - "alga 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "include_dir 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "proptest-derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "toml 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "yaml-rust" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yaml-rust" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" -"checksum alga 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d708cb68c7106ed1844de68f50f0157a7788c2909a6926fad5a87546ef6a4ff8" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" -"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" -"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" -"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 atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" -"checksum backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "18b50f5258d1a9ad8396d2d345827875de4261b158124d4c819d9b351454fae5" -"checksum backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61" -"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" -"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" -"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" -"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" -"checksum bstr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc0572e02f76cb335f309b19e0a0d585b4f62788f7d26de2a13a836a637385f" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" -"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" -"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9107d78ed62b3fa5a86e7d18e647abed48cfd8f8fab6c72f4cdb982d196f7e6" -"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" -"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" -"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" -"checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -"checksum downcast-rs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b92dfd5c2f75260cbf750572f95d387e7ca0ba5e3fbe9e1a33f23025be020f" -"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" -"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" -"checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd" -"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 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" -"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" -"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" -"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" -"checksum include_dir 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f41a8bee1894b3fb755d8f09ccd764650476358197a0582555f698fe84b0ae93" -"checksum include_dir_impl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b029199aef0fb9921fdc5623843197e6f4a035774523817599a9f55e4bf3b" -"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" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum lexical-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3f8673fab7063c2cac37d299c8a1a7beb720e78f71500098e4a3c137fdf025bf" -"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" -"checksum libm 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" -"checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" -"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum log-mdc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a94d21414c1f4a51209ad204c1776a3d0765002c76c6abcb602a6f09f1e881c7" -"checksum log4rs 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "100052474df98158c0738a7d3f4249c99978490178b5f9f68cd835ac57adbd1b" -"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" -"checksum miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c468f2369f07d651a5d0bb2c9079f8488a66d5466efe42d0c5c6466edcb7f71e" -"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" -"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 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b" -"checksum num-complex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fcb0cf31fb3ff77e6d2a6ebd6800df7fdcd106f2ad89113c9130bcd07f93dffc" -"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" -"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518" -"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" -"checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" -"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8" -"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a" -"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -"checksum proptest 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2afed8cbdc8a64b58a5c021757a782351ec1afee85be374872721c84d5da5d80" -"checksum proptest-derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08b264c54525e760fc1d39c5b2bfc96923b922a752893053b4adaafe33fa9346" -"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" -"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e193067942ef6f485a349a113329140d0ab9e2168ce92274499bb0e9a4190d9d" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe5204c3a17e97dde73f285d49be585df59ed84b50a872baf416e73b62c3828" -"checksum regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b2f0808e7d7e4fb1cb07feb6ff2f4bc827938f24f8c2e6a3beb7370af544bdd" -"checksum regex-automata 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ed09217220c272b29ef237a974ad58515bde75f194e3ffa7e6d0bf0f3b01f86" -"checksum regex-syntax 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dcfd8681eebe297b81d98498869d4aae052137651ad7b96822f09ceb690d0a96" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" -"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae" -"checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" -"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" -"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"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.92 (registry+https://github.com/rust-lang/crates.io-index)" = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be" -"checksum serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153" -"checksum serde-value 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" -"checksum serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)" = "46a3223d0c9ba936b61c0d2e3e559e3217dbfb8d65d06d26e8b3c25de38bae3e" -"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" -"checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582" -"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" -"checksum stackvector 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1c4725650978235083241fab0fdc8e694c3de37821524e7534a1a9061d1068af" -"checksum static_assertions 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" -"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.35 (registry+https://github.com/rust-lang/crates.io-index)" = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3" -"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -"checksum tempfile 3.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dc4738f2e68ed2855de5ac9cdbe05c9216773ecde4739b2f095002ab03a13ef" -"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" -"checksum termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dde0593aeb8d47accea5392b39350015b5eccb12c0d98044d856983d89548dea" -"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" -"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 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 traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" -"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992" -"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 1ac8853f472d..000000000000 --- a/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "xanthous" -version = "0.1.0" -authors = ["Griffin Smith <root@gws.fyi>"] -edition = "2018" - -[dependencies] -alga = "0.9.1" -backtrace = "0.3" -clap = {version = "^2.33.0", features = ["yaml"]} -config = "*" -downcast-rs = "^1.0.4" -futures = "0.1.28" -include_dir = "0.2.1" -itertools = "*" -lazy_static = "*" -log = "*" -log4rs = "*" -maplit = "^1.0.1" -matches = "0.1.8" -nom = "^5.0.0" -prettytable-rs = "^0.8" -proptest = "0.9.3" -proptest-derive = "*" -rand = {version = "^0.7.0", features = ["small_rng"]} -serde = "^1.0.8" -serde_derive = "^1.0.8" -serde_json = "*" -serde_yaml = "0.8" -termion = "*" -toml = "^0.5.1" - -[dev-dependencies] diff --git a/Config.toml b/Config.toml deleted file mode 100644 index 30806365d28f..000000000000 --- a/Config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[logging] -level = "debug" diff --git a/proptest-regressions/description.txt b/proptest-regressions/description.txt deleted file mode 100644 index 3c4942315b45..000000000000 --- a/proptest-regressions/description.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 92b51b5444b913aaa6cb89d7e7175ab6a6af5b5231ba047d123bb55d43d7d272 # shrinks to descriptions = [] diff --git a/proptest-regressions/display/draw_box.txt b/proptest-regressions/display/draw_box.txt deleted file mode 100644 index 03391a696de8..000000000000 --- a/proptest-regressions/display/draw_box.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 7aff36a9f7b263e62434a3f61ada1d6aaf6ff4545a463548d96815a0e98cf5f1 # shrinks to dims = Dimensions { w: 0, h: 0 }, style = Thin -cc e4d96a13d6a8c7625e49d3545f6076d58152f3b5eb43fae65f0d407d1d34f96c # shrinks to dims = Dimensions { w: 1, h: 1 }, style = Thin -cc b5f0d7cb409896bd6692544c7c1f781174075c287d3b7a3b9dc73526ea489484 # shrinks to dims = Dimensions { w: 1, h: 1 }, style = Thin -cc 103b62b7c29c22adcbc23153638d3b37bad57aeec685d1eab38c49d0deed937f # shrinks to dims = Dimensions { w: 0, h: 1 }, style = Thin -cc 24c3858a543b0d8ff4966517040ec8c183ed311688d6863fd13facb5cdad7aa0 # shrinks to dims = Dimensions { w: 1, h: 1 }, style = Thin -cc 70a53a8b771937976a08a72d870b355a0995cc0251f45de4393c37a56a789b83 # shrinks to dims = Dimensions { w: 0, h: 0 }, style = Thin diff --git a/proptest-regressions/display/viewport.txt b/proptest-regressions/display/viewport.txt deleted file mode 100644 index e38056d975ff..000000000000 --- a/proptest-regressions/display/viewport.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc b84a5a6dbba5cfc69329a119d9e20328c0372e0db2b72e5d71d971e3f13f8749 # shrinks to pos = Position { x: 0, y: 0 }, outer = BoundingBox { dimensions: Dimensions { w: 0, h: 0 }, position: Position { x: 0, y: 0 } } diff --git a/proptest-regressions/types/entity_map.txt b/proptest-regressions/types/entity_map.txt deleted file mode 100644 index 68be5752f4e0..000000000000 --- a/proptest-regressions/types/entity_map.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 16afe2473971397314ffa77acf7bad62f0c40bc3f591aff7aa9193c29e5a0921 # shrinks to items = [(Position { x: 92, y: 60 }, ""), (Position { x: 92, y: 60 }, "")] -cc 3a68a382c3bb8fdf60ea150a369abbdd45859e0c54cd6a4f7c75937a6c783b98 # shrinks to mut em = EntityMap { by_position: {Position { x: 25, y: 33 }: [1]}, by_id: {1: TestEntity { position: Position { x: 25, y: 33 }, name: "" }}, last_id: 1 }, ent = TestEntity { position: Position { x: 25, y: 33 }, name: "" }, new_position = Position { x: 0, y: 0 } -cc ffd7181e1c0343ab4c2ac92990f068d24c8663158c1c0a9526cd9edc470f950a # shrinks to mut em = EntityMap { by_position: {Position { x: 64, y: 58 }: [1]}, by_id: {1: TestEntity { position: Position { x: 64, y: 58 }, name: "" }}, last_id: 1 }, ent = TestEntity { position: Position { x: 0, y: 0 }, name: "" }, new_position = Position { x: 64, y: 58 } diff --git a/proptest-regressions/types/mod.txt b/proptest-regressions/types/mod.txt deleted file mode 100644 index 276466965c44..000000000000 --- a/proptest-regressions/types/mod.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc a51cf37623f0e4024f4ba1450195be296d9b9e8ae954dbbf997ce5b57cd26792 # shrinks to a = Position { x: 44, y: 25 }, b = Position { x: 0, y: 25 }, c = Position { x: 0, y: 0 } -cc 0816b9348c53ef8c8328f0ea72d5ebef215f6764b1cbbd3c5db958e214c5fa3a # shrinks to pos = Position { x: 0, y: 0 }, dir = Down diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index df99c69198f5..000000000000 --- a/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -max_width = 80 diff --git a/src/cli.yml b/src/cli.yml deleted file mode 100644 index 4b2e94e57b0e..000000000000 --- a/src/cli.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: xanthous -version: "0.0" -author: Griffin Smith <root@gws.fyi> -about: hey, it's a terminal game -args: - - config: - short: c - long: config - value_name: FILE - help: Sets a custom config file - takes_value: true -subcommands: - - info: - about: Writes debug information to the terminal and exits - - generate-level: - about: Generate a level and print it to the screen - args: - - generator: - long: generator - value_name: GEN - help: Select which generator to use - takes_value: true - - width: - long: width - short: w - value_name: WIDTH - takes_value: true - - height: - long: height - short: h - value_name: HEIGHT - takes_value: true - - start-alive-chance: - long: start-alive-chance - takes_value: true - - birth_limit: - long: birth-limit - takes_value: true - - death_limit: - long: death-limit - takes_value: true - - steps: - long: steps - short: s - value_name: STEPS - takes_value: true diff --git a/src/description.rs b/src/description.rs deleted file mode 100644 index 48c98d76e051..000000000000 --- a/src/description.rs +++ /dev/null @@ -1,93 +0,0 @@ -use crate::entities::Describe; - -pub fn list_to_sentence(lst: &[String]) -> String { - let mut buf = String::with_capacity( - lst.iter() - .map(|e| e.len() + 2usize /* ", " */) - .sum::<usize>() - + if lst.len() >= 3 { - 3usize /* "and" */ - } else { - 0usize - }, - ); - - match lst.len() { - 0 => {} - 1 => buf.push_str(&lst[0]), - 2 => { - buf.push_str(&lst[0]); - buf.push_str(" and "); - buf.push_str(&lst[1]); - } - _ => { - for desc in &lst[..lst.len() - 1] { - buf.push_str(desc); - buf.push_str(", "); - } - buf.push_str("and "); - buf.push_str(&lst[lst.len() - 1]); - } - } - - buf -} - -pub fn describe_list<A: Describe>(lst: &[A]) -> String { - list_to_sentence( - &lst.iter().map(|e| e.description()).collect::<Vec<String>>(), - ) -} - -#[cfg(test)] -mod tests { - use super::*; - use proptest::prelude::*; - use proptest_derive::Arbitrary; - - #[derive(Debug, Arbitrary)] - struct Description(String); - - impl Describe for Description { - fn description(&self) -> String { - self.0.clone() - } - } - - proptest! { - #[test] - fn test_describe_list_includes_all_descriptions( - descriptions: Vec<Description> - ) { - let res = describe_list(&descriptions); - for Description(desc) in descriptions { - assert!(res.contains(&desc)); - } - } - } - - #[test] - fn test_describe_list() { - assert_eq!( - describe_list(&[Description("one".to_string())]), - "one".to_string() - ); - - assert_eq!( - describe_list(&[ - Description("one".to_string()), - Description("two".to_string()) - ]), - "one and two".to_string() - ); - - assert_eq!( - describe_list(&[ - Description("one".to_string()), - Description("two".to_string()), - Description("three".to_string()) - ]), - "one, two, and three".to_string() - ); - } -} diff --git a/src/display/color.rs b/src/display/color.rs deleted file mode 100644 index afe0039998b8..000000000000 --- a/src/display/color.rs +++ /dev/null @@ -1,163 +0,0 @@ -use serde::de::{self, Unexpected, Visitor}; -use std::fmt; -use std::marker::PhantomData; -use termion::color; - -#[derive(Debug)] -pub struct Color(Box<dyn color::Color>); - -unsafe impl Sync for Color {} -unsafe impl Send for Color {} - -impl Color { - pub fn new<C: color::Color + 'static>(c: C) -> Self { - Color(Box::new(c)) - } -} - -impl PartialEq for Color { - fn eq(&self, other: &Self) -> bool { - format!("{}{}", color::Fg(self), color::Bg(self)) - == format!("{}{}", color::Fg(other), color::Bg(other)) - } -} - -impl Eq for Color {} - -impl color::Color for Color { - fn write_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.write_fg(f) - } - - fn write_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.write_bg(f) - } -} - -impl<'a> color::Color for &'a Color { - fn write_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.write_fg(f) - } - - fn write_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.write_bg(f) - } -} - -impl Default for Color { - fn default() -> Self { - Color::new(color::Reset) - } -} - -pub struct ColorVisitor { - marker: PhantomData<fn() -> Color>, -} - -impl ColorVisitor { - fn new() -> Self { - ColorVisitor { - marker: PhantomData, - } - } -} - -impl<'de> Visitor<'de> for ColorVisitor { - type Value = Color; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("A color") - } - - fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> - where - E: de::Error, - { - match v.to_lowercase().as_ref() { - "black" => Ok(Color(Box::new(color::Black))), - "blue" => Ok(Color(Box::new(color::Blue))), - "cyan" => Ok(Color(Box::new(color::Cyan))), - "green" => Ok(Color(Box::new(color::Green))), - "light black" | "light_black" => { - Ok(Color(Box::new(color::LightBlack))) - } - "light blue" | "light_blue" => { - Ok(Color(Box::new(color::LightBlue))) - } - "light cyan" | "light_cyan" => { - Ok(Color(Box::new(color::LightCyan))) - } - "light green" | "light_green" => { - Ok(Color(Box::new(color::LightGreen))) - } - "light magenta" | "light_magenta" => { - Ok(Color(Box::new(color::LightMagenta))) - } - "light red" | "light_red" => Ok(Color(Box::new(color::LightRed))), - "light white" | "light_white" => { - Ok(Color(Box::new(color::LightWhite))) - } - "light yellow" | "light_yellow" => { - Ok(Color(Box::new(color::LightYellow))) - } - "magenta" => Ok(Color(Box::new(color::Magenta))), - "red" => Ok(Color(Box::new(color::Red))), - "white" => Ok(Color(Box::new(color::White))), - "yellow" => Ok(Color(Box::new(color::Yellow))), - _ => Err(de::Error::invalid_value( - Unexpected::Str(v), - &"a valid color", - )), - } - } - - fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error> - where - A: de::MapAccess<'de>, - { - let mut red = None; - let mut green = None; - let mut blue = None; - while let Some((k, v)) = map.next_entry()? { - match k { - "red" => { - red = Some(v); - } - "green" => { - green = Some(v); - } - "blue" => { - blue = Some(v); - } - _ => { - return Err(de::Error::unknown_field( - k, - &["red", "green", "blue"], - )); - } - } - } - - match (red, green, blue) { - (Some(r), Some(g), Some(b)) => { - Ok(Color(Box::new(color::Rgb(r, g, b)))) - } - (None, _, _) => Err(de::Error::missing_field("red")), - (_, None, _) => Err(de::Error::missing_field("green")), - (_, _, None) => Err(de::Error::missing_field("blue")), - } - } - - fn visit_u8<E: de::Error>(self, v: u8) -> Result<Self::Value, E> { - Ok(Color(Box::new(color::AnsiValue(v)))) - } -} - -impl<'de> serde::Deserialize<'de> for Color { - fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> - where - D: serde::Deserializer<'de>, - { - deserializer.deserialize_any(ColorVisitor::new()) - } -} diff --git a/src/display/draw_box.rs b/src/display/draw_box.rs deleted file mode 100644 index e4d34a7acda9..000000000000 --- a/src/display/draw_box.rs +++ /dev/null @@ -1,274 +0,0 @@ -use crate::display::utils::clone_times; -use crate::display::utils::times; -use crate::types::pos; -use crate::types::BoundingBox; -use crate::types::Dimensions; -use crate::types::Neighbors; -use itertools::Itertools; -use proptest::prelude::Arbitrary; -use proptest::strategy; -use proptest_derive::Arbitrary; -use std::io::{self, Write}; - -// Box Drawing -// 0 1 2 3 4 5 6 7 8 9 A B C D E F -// U+250x โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ -// U+251x โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ -// U+252x โ โก โข โฃ โค โฅ โฆ โง โจ โฉ โช โซ โฌ โญ โฎ โฏ -// U+253x โฐ โฑ โฒ โณ โด โต โถ โท โธ โน โบ โป โผ โฝ โพ โฟ -// U+254x โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ -// U+255x โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ โ -// U+256x โ โก โข โฃ โค โฅ โฆ โง โจ โฉ โช โซ โฌ โญ โฎ โฏ -// U+257x โฐ โฑ โฒ โณ โด โต โถ โท โธ โน โบ โป โผ โฝ โพ โฟ - -static BOX: char = 'โ'; - -static BOX_CHARS: [[char; 16]; 8] = [ - // 0 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ ', 'โ', 'โ', 'โ', 'โ', - // 10 - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - ], - // 1 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - ], - // 2 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ ', 'โก', 'โข', 'โฃ', 'โค', 'โฅ', 'โฆ', 'โง', 'โจ', 'โฉ', - 'โช', 'โซ', 'โฌ', 'โญ', 'โฎ', 'โฏ', - ], - // 3 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โฐ', 'โฑ', 'โฒ', 'โณ', 'โด', 'โต', 'โถ', 'โท', 'โธ', 'โน', - 'โบ', 'โป', 'โผ', 'โฝ', 'โพ', 'โฟ', - ], - // 4 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ ', 'โ', 'โ', 'โ', 'โ', - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - ], - // 5 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - 'โ', 'โ', 'โ', 'โ', 'โ', 'โ', - ], - // 6 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โ ', 'โก', 'โข', 'โฃ', 'โค', 'โฅ', 'โฆ', 'โง', 'โจ', 'โฉ', - 'โช', 'โซ', 'โฌ', 'โญ', 'โฎ', 'โฏ', - ], - // 7 - [ - // 0 1 2 3 4 5 6 7 8 9 - 'โฐ', 'โฑ', 'โฒ', 'โณ', 'โด', 'โต', 'โถ', 'โท', 'โธ', 'โน', - 'โบ', 'โป', 'โผ', 'โฝ', 'โพ', 'โฟ', - ], -]; - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum BoxStyle { - Thin, - Thick, - Dotted, - ThickDotted, - Dashed, - ThickDashed, - Double, -} - -impl Arbitrary for BoxStyle { - type Parameters = (); - type Strategy = strategy::Just<Self>; - fn arbitrary_with(_: Self::Parameters) -> Self::Strategy { - // TODO - strategy::Just(BoxStyle::Thin) - } -} - -pub trait Stylable { - fn style(&self, style: BoxStyle) -> char; -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -enum Corner { - TopRight, - TopLeft, - BottomRight, - BottomLeft, -} - -impl Stylable for Corner { - fn style(&self, style: BoxStyle) -> char { - use BoxStyle::*; - use Corner::*; - - match (self, style) { - (TopRight, Thin) => BOX_CHARS[1][0], - (TopLeft, Thin) => BOX_CHARS[0][12], - (BottomRight, Thin) => BOX_CHARS[1][8], - (BottomLeft, Thin) => BOX_CHARS[1][4], - _ => unimplemented!(), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -enum Line { - H, - V, -} - -impl Stylable for Line { - fn style(&self, style: BoxStyle) -> char { - use BoxStyle::*; - use Line::*; - match (self, style) { - (H, Thin) => BOX_CHARS[0][0], - (V, Thin) => BOX_CHARS[0][2], - _ => unimplemented!(), - } - } -} - -impl Stylable for Neighbors<Option<BoxStyle>> { - fn style(&self, _style: BoxStyle) -> char { - use BoxStyle::*; - match (self.left, self.right, self.top, self.bottom) { - (None, None, None, None) => BOX, - (Some(Thin), None, None, None) => BOX_CHARS[7][4], - (None, Some(Thin), None, None) => BOX_CHARS[7][6], - (None, None, Some(Thin), None) => BOX_CHARS[7][5], - (None, None, None, Some(Thin)) => BOX_CHARS[7][7], - (Some(Thin), Some(Thin), None, None) => Line::H.style(Thin), - (Some(Thin), None, Some(Thin), None) => { - Corner::BottomRight.style(Thin) - } - (Some(Thin), None, None, Some(Thin)) => { - Corner::TopRight.style(Thin) - } - (None, Some(Thin), Some(Thin), None) => { - Corner::BottomLeft.style(Thin) - } - (None, Some(Thin), None, Some(Thin)) => Corner::TopLeft.style(Thin), - (None, None, Some(Thin), Some(Thin)) => Line::V.style(Thin), - (None, Some(Thin), Some(Thin), Some(Thin)) => BOX_CHARS[1][12], - (Some(Thin), None, Some(Thin), Some(Thin)) => BOX_CHARS[2][4], - (Some(Thin), Some(Thin), None, Some(Thin)) => BOX_CHARS[2][12], - (Some(Thin), Some(Thin), Some(Thin), None) => BOX_CHARS[3][4], - (Some(Thin), Some(Thin), Some(Thin), Some(Thin)) => { - BOX_CHARS[3][12] - } - neighs => panic!("unimplemented: {:?}", neighs), - } - } -} - -#[must_use] -pub fn make_box(style: BoxStyle, dims: Dimensions) -> String { - if dims.h == 0 || dims.w == 0 { - "".to_string() - } else if dims.h == 1 && dims.w == 1 { - BOX.to_string() - } else if dims.h == 1 { - times(Line::H.style(style), dims.w) - } else if dims.w == 1 { - (0..dims.h).map(|_| Line::V.style(style)).join("\n\r") - } else { - let h_line: String = times(Line::H.style(style), dims.w - 2); - let v_line = Line::V.style(style); - let v_walls: String = clone_times( - format!( - "{}{}{}\n\r", - v_line, - times::<_, String>(' ', dims.w - 2), - v_line - ), - dims.h - 2, - ); - - format!( - "{}{}{}\n\r{}{}{}{}", - Corner::TopLeft.style(style), - h_line, - Corner::TopRight.style(style), - v_walls, - Corner::BottomLeft.style(style), - h_line, - Corner::BottomRight.style(style), - ) - } -} - -/// Draw the box described by the given BoundingBox's position and dimensions to -/// the given output, with the given style -pub fn draw_box<W: Write>( - out: &mut W, - bbox: BoundingBox, - style: BoxStyle, -) -> io::Result<()> { - let box_str = make_box(style, bbox.dimensions); - if bbox.position.x == 0 { - write!(out, "{}{}", bbox.position.cursor_goto(), box_str)?; - } else { - for (i, line) in box_str.split("\n\r").enumerate() { - debug!("line: {:?}!", line); - write!( - out, - "{}{}", - (bbox.position + pos(0, i as i16)).cursor_goto(), - line - )?; - } - } - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - use proptest::prelude::*; - - #[test] - fn make_thin_box() { - let res = make_box(BoxStyle::Thin, Dimensions { w: 10, h: 10 }); - assert_eq!( - res, - "โโโโโโโโโโ -\rโ โ -\rโ โ -\rโ โ -\rโ โ -\rโ โ -\rโ โ -\rโ โ -\rโ โ -\rโโโโโโโโโโ" - ); - } - - proptest! { - #[test] - fn box_has_height_lines(dims: Dimensions, style: BoxStyle) { - let res = make_box(style, dims); - prop_assume!((dims.w > 0 && dims.h > 0)); - assert_eq!(res.split("\n\r").count(), dims.h as usize); - } - - #[test] - fn box_lines_have_width_length(dims: Dimensions, style: BoxStyle) { - let res = make_box(style, dims); - prop_assume!(dims.w == 0 && dims.h == 0 || (dims.w > 0 && dims.h > 0)); - assert!(res.split("\n\r").all(|l| l.chars().count() == dims.w as usize)); - } - } -} diff --git a/src/display/mod.rs b/src/display/mod.rs deleted file mode 100644 index 6e37a03d8c55..000000000000 --- a/src/display/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -pub mod color; -pub mod draw_box; -pub mod utils; -pub mod viewport; -use crate::entities::entity::Entity; -use crate::types::Neighbors; -use crate::types::Positioned; -pub use draw_box::{make_box, BoxStyle}; -use std::io::{self, Write}; -use termion::{clear, cursor, style}; -pub use viewport::Viewport; - -pub fn clear<T: Write>(out: &mut T) -> io::Result<()> { - write!(out, "{}{}{}", clear::All, style::Reset, cursor::Goto(1, 1)) -} - -pub trait Draw: Positioned { - /// Draw this entity, assuming the character is already at the correct - /// position - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()>; -} - -impl<T: Draw> Draw for &T { - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()> { - (**self).do_draw(out) - } -} - -impl<T: Draw> Draw for Box<T> { - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()> { - (**self).do_draw(out) - } -} - -pub trait DrawWithNeighbors: Positioned { - #[allow(clippy::borrowed_box)] - fn do_draw_with_neighbors<'a, 'b>( - &'a self, - out: &'b mut dyn Write, - neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>, - ) -> io::Result<()>; -} - -impl<T: Draw> DrawWithNeighbors for T { - fn do_draw_with_neighbors<'a, 'b>( - &'a self, - out: &'b mut dyn Write, - _neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>, - ) -> io::Result<()> { - self.do_draw(out) - } -} diff --git a/src/display/utils.rs b/src/display/utils.rs deleted file mode 100644 index acd4416cb884..000000000000 --- a/src/display/utils.rs +++ /dev/null @@ -1,9 +0,0 @@ -use std::iter::FromIterator; - -pub fn times<A: Copy, B: FromIterator<A>>(elem: A, n: u16) -> B { - (0..n).map(|_| elem).collect() -} - -pub fn clone_times<A: Clone, B: FromIterator<A>>(elem: A, n: u16) -> B { - (0..n).map(|_| elem.clone()).collect() -} diff --git a/src/display/viewport.rs b/src/display/viewport.rs deleted file mode 100644 index c44316cdaad5..000000000000 --- a/src/display/viewport.rs +++ /dev/null @@ -1,303 +0,0 @@ -use super::BoxStyle; -use super::DrawWithNeighbors; -use crate::display::draw_box::draw_box; -use crate::display::utils::clone_times; -use crate::entities::entity::Entity; -use crate::types::menu::MenuInfo; -use crate::types::Neighbors; -use crate::types::{pos, BoundingBox, Direction, Position, Positioned}; -use std::fmt::{self, Debug}; -use std::io::{self, Write}; - -pub enum CursorState { - Game, - Prompt(Position), -} - -impl Default for CursorState { - fn default() -> Self { - CursorState::Game - } -} - -pub struct Viewport<W> { - /// The box describing the visible part of the viewport. - /// - /// Generally the size of the terminal, and positioned at 0, 0 - pub outer: BoundingBox, - - /// The box describing the game part of the viewport. - pub game: BoundingBox, - - /// The box describing the inner part of the viewport - /// - /// Its position is relative to `outer.inner()`, and its size should - /// generally not be smaller than outer - pub inner: BoundingBox, - - /// The actual screen that the viewport writes to - pub out: W, - - cursor_state: CursorState, - - /// Reset the cursor back to this position after every draw - pub game_cursor_position: Position, -} - -impl<W> Viewport<W> { - pub fn new(outer: BoundingBox, inner: BoundingBox, out: W) -> Self { - Viewport { - outer, - inner, - out, - game: outer.move_tr_corner(Position { x: 0, y: 1 }), - cursor_state: Default::default(), - game_cursor_position: pos(0, 0), - } - } - - /// Returns true if the (inner-relative) position of the given entity is - /// visible within this viewport - pub fn visible<E: Positioned>(&self, ent: &E) -> bool { - self.on_screen(ent.position()).within(self.game.inner()) - } - - /// Convert the given inner-relative position to one on the actual screen - fn on_screen(&self, pos: Position) -> Position { - pos + self.inner.position + self.game.inner().position - } -} - -impl<W> Debug for Viewport<W> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "Viewport {{ outer: {:?}, inner: {:?}, out: <OUT> }}", - self.outer, self.inner - ) - } -} - -impl<W: Write> Viewport<W> { - /// Draw the given entity to the viewport at its position, if visible - #[allow(clippy::borrowed_box)] - pub fn draw<T: DrawWithNeighbors>( - &mut self, - entity: &T, - neighbors: &Neighbors<Vec<&Box<dyn Entity>>>, - ) -> io::Result<()> { - if !self.visible(entity) { - return Ok(()); - } - self.cursor_goto(entity.position())?; - entity.do_draw_with_neighbors(self, neighbors)?; - self.reset_cursor() - } - - fn reset_cursor(&mut self) -> io::Result<()> { - self.cursor_goto(self.game_cursor_position) - } - - /// Move the cursor to the given inner-relative position - pub fn cursor_goto(&mut self, pos: Position) -> io::Result<()> { - write!(self, "{}", self.on_screen(pos).cursor_goto()) - } - - /// Clear whatever single character is drawn at the given inner-relative - /// position, if visible - pub fn clear(&mut self, pos: Position) -> io::Result<()> { - write!(self, "{} ", self.on_screen(pos).cursor_goto(),)?; - self.reset_cursor() - } - - /// Initialize this viewport by drawing its outer box to the screen - pub fn init(&mut self) -> io::Result<()> { - draw_box(self, self.game, BoxStyle::Thin) - } - - /// Write a message to the message area on the screen - /// - /// Will overwrite any message already present, and if the given message is - /// longer than the screen will truncate. This means callers should handle - /// message buffering and ellipsisization - pub fn write_message(&mut self, msg: &str) -> io::Result<usize> { - let msg_to_write = if msg.len() <= self.outer.dimensions.w as usize { - msg - } else { - &msg[0..self.outer.dimensions.w as usize] - }; - write!( - self, - "{}{}{}", - self.outer.position.cursor_goto(), - msg_to_write, - clone_times::<_, String>( - " ".to_string(), - self.outer.dimensions.w - msg.len() as u16 - ), - )?; - self.reset_cursor()?; - Ok(msg_to_write.len()) - } - - pub fn clear_message(&mut self) -> io::Result<()> { - write!( - self, - "{}{}", - self.outer.position.cursor_goto(), - clone_times::<_, String>( - " ".to_string(), - self.outer.dimensions.w as u16 - ) - )?; - self.reset_cursor() - } - - /// Write a prompt requesting text input to the message area on the screen. - /// - /// Will overwrite any message already present, and if the given message is - /// longer than the screen will truncate. This means callers should handle - /// message buffering and ellipsisization - pub fn write_prompt<'a, 'b>(&'a mut self, msg: &'b str) -> io::Result<()> { - let len = self.write_message(msg)? + 1; - let pos = self.outer.position + pos(len as i16, 0); - self.cursor_state = CursorState::Prompt(pos); - write!(self, "{}", pos.cursor_goto())?; - self.flush() - } - - pub fn push_prompt_chr(&mut self, chr: char) -> io::Result<()> { - if let CursorState::Prompt(pos) = self.cursor_state { - write!(self, "{}", chr)?; - self.cursor_state = CursorState::Prompt(pos + Direction::Right); - } - Ok(()) - } - - pub fn pop_prompt_chr(&mut self) -> io::Result<()> { - if let CursorState::Prompt(pos) = self.cursor_state { - let new_pos = pos + Direction::Left; - write!( - self, - "{} {}", - new_pos.cursor_goto(), - new_pos.cursor_goto() - )?; - self.cursor_state = CursorState::Prompt(new_pos); - } - Ok(()) - } - - pub fn clear_prompt(&mut self) -> io::Result<()> { - self.clear_message()?; - self.cursor_state = CursorState::Game; - Ok(()) - } - - pub fn write_menu(&mut self, menu: &MenuInfo) -> io::Result<()> { - let menu_dims = menu.dimensions(); - - // TODO: check if the menu is too big - - let menu_position = self.game.position + pos(1, 1); - - let menu_box = BoundingBox { - dimensions: menu_dims, - position: menu_position, - }; - - debug!("writing menu at: {:?}", menu_box); - - draw_box(self, menu_box, BoxStyle::Thin)?; - - write!( - self, - "{}{}", - (menu_position + pos(2, 2)).cursor_goto(), - menu.prompt - )?; - - for (idx, option) in menu.options.iter().enumerate() { - write!( - self, - "{}{}", - (menu_position + pos(2, 4 + idx as i16)).cursor_goto(), - option - )?; - } - - Ok(()) - } -} - -impl<W> Positioned for Viewport<W> { - fn position(&self) -> Position { - self.outer.position - } -} - -impl<W: Write> Write for Viewport<W> { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.out.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.out.flush() - } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.out.write_all(buf) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::types::Dimensions; - - #[test] - fn test_visible() { - assert!(Viewport::new( - BoundingBox::at_origin(Dimensions { w: 10, h: 10 }), - BoundingBox { - position: Position { x: -10, y: -10 }, - dimensions: Dimensions { w: 15, h: 15 }, - }, - () - ) - .visible(&Position { x: 13, y: 13 })); - - assert!(!Viewport::new( - BoundingBox::at_origin(Dimensions { w: 10, h: 10 }), - BoundingBox { - position: Position { x: -10, y: -10 }, - dimensions: Dimensions { w: 15, h: 15 }, - }, - (), - ) - .visible(&Position { x: 1, y: 1 })); - } - - #[test] - fn test_write_menu() { - let buf: Vec<u8> = Vec::new(); - - let mut viewport = Viewport::new( - BoundingBox::at_origin(Dimensions::default()), - BoundingBox::at_origin(Dimensions::default()), - buf, - ); - - let menu = MenuInfo::new( - "Test menu".to_string(), - vec!["option 1".to_string(), "option 2".to_string()], - ); - - viewport.write_menu(&menu).unwrap(); - - let res = std::str::from_utf8(&viewport.out).unwrap(); - assert!(res.contains("Test menu")); - assert!(res.contains("option 1")); - assert!(res.contains("option 2")); - } -} diff --git a/src/entities/character.rs b/src/entities/character.rs deleted file mode 100644 index 3e8336b129ff..000000000000 --- a/src/entities/character.rs +++ /dev/null @@ -1,51 +0,0 @@ -use crate::display; -use crate::entities::item::Item; -use crate::types::{Position, Speed}; -use std::io::{self, Write}; - -const DEFAULT_SPEED: Speed = Speed(100); - -entity! { - pub struct Character { - pub o_name: Option<String>, - pub inventory: Vec<Box<Item>>, - } -} - -static_description!(Character, "yourself"); - -impl Character { - pub fn new() -> Character { - Character { - id: None, - position: Position { x: 0, y: 0 }, - o_name: None, - inventory: Vec::new(), - } - } - - pub fn speed(&self) -> Speed { - Speed(100) - } - - pub fn damage(&self) -> u16 { - // TODO - 1 - } - - pub fn name(&self) -> &str { - self.o_name - .as_ref() - .expect("Character name not initialized") - } - - pub fn set_name(&mut self, name: String) { - self.o_name = Some(name); - } -} - -impl display::Draw for Character { - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()> { - write!(out, "@") - } -} diff --git a/src/entities/creature.rs b/src/entities/creature.rs deleted file mode 100644 index 20071c1d88eb..000000000000 --- a/src/entities/creature.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::display; -use crate::entities::raws::CreatureType; -use crate::entities::raws::EntityRaw; -use crate::entities::{raw, Describe, EntityID}; -use crate::types::Position; -use std::io::{self, Write}; - -#[derive(Debug, Clone)] -pub struct Creature { - pub id: Option<EntityID>, - pub typ: &'static CreatureType<'static>, - pub position: Position, - pub hitpoints: u16, -} - -impl Creature { - pub fn new_from_raw(name: &'static str, position: Position) -> Self { - match raw(name) { - EntityRaw::Creature(typ) => Self::new_with_type(typ, position), - _ => panic!("Invalid raw type for {:?}, expected Creature", name), - } - } - - pub fn new_with_type( - typ: &'static CreatureType<'static>, - position: Position, - ) -> Self { - Creature { - id: None, - typ, - position, - hitpoints: typ.max_hitpoints, - } - } - - /// Damage the given creature by the given amount - pub fn damage(&mut self, amount: u16) { - if self.hitpoints <= amount { - self.hitpoints = 0; - } else { - self.hitpoints -= amount; - } - } - - /// Returns true if this creature has died - pub fn dead(&self) -> bool { - self.hitpoints == 0 - } -} - -entity!(Creature); - -impl Describe for Creature { - fn description(&self) -> String { - self.typ.description.to_string() - } -} - -impl display::Draw for Creature { - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()> { - write!(out, "{}", self.typ.chr) - } -} diff --git a/src/entities/entity.rs b/src/entities/entity.rs deleted file mode 100644 index 01075d298f81..000000000000 --- a/src/entities/entity.rs +++ /dev/null @@ -1,125 +0,0 @@ -use crate::display::DrawWithNeighbors; -use crate::entities::EntityID; -use crate::types::Neighbors; -use crate::types::Position; -use crate::types::{Positioned, PositionedMut}; -use downcast_rs::Downcast; -use std::fmt::Debug; -use std::io::{self, Write}; - -pub trait Identified<ID>: Debug { - fn opt_id(&self) -> Option<ID>; - fn set_id(&mut self, id: ID); - - fn id(&self) -> ID { - self.opt_id() - .unwrap_or_else(|| panic!("Entity ({:?}) is not in the game", self)) - } -} - -impl<'a, A, ID> Identified<ID> for &'a mut A -where - A: Identified<ID>, -{ - fn opt_id(&self) -> Option<ID> { - (**self).opt_id() - } - fn set_id(&mut self, id: ID) { - (**self).set_id(id); - } -} - -impl<ID, A: Identified<ID>> Identified<ID> for Box<A> { - fn opt_id(&self) -> Option<ID> { - (**self).opt_id() - } - fn set_id(&mut self, id: ID) { - (**self).set_id(id); - } -} - -pub trait Describe { - fn description(&self) -> String; -} - -ref_impl! { - impl<T: Describe> Describe for &T { - fn description(&self) -> String { - (**self).description() - } - } -} - -#[macro_export] -macro_rules! static_description { - ($name: ident, $description: expr) => { - impl $crate::entities::entity::Describe for $name { - fn description(&self) -> String { - $description.to_string() - } - } - }; -} - -pub trait Entity: - Positioned - + PositionedMut - + Identified<EntityID> - + DrawWithNeighbors - + Downcast - + Describe -{ -} - -impl Identified<EntityID> for Box<dyn Entity> { - fn opt_id(&self) -> Option<EntityID> { - (**self).opt_id() - } - fn set_id(&mut self, id: EntityID) { - (**self).set_id(id); - } -} - -#[macro_export] -macro_rules! identified { - ($name: ident, $typ: path) => { - identified!($name, $typ, id); - }; - ($name: ident, $typ: path, $attr: ident) => { - impl crate::entities::entity::Identified<$typ> for $name { - fn opt_id(&self) -> Option<$typ> { - self.$attr - } - - fn set_id(&mut self, id: $typ) { - self.$attr = Some(id) - } - } - }; -} - -impl_downcast!(Entity); - -impl DrawWithNeighbors for Box<dyn Entity> { - fn do_draw_with_neighbors<'a, 'b>( - &'a self, - out: &'b mut dyn Write, - neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>, - ) -> io::Result<()> { - (**self).do_draw_with_neighbors(out, neighbors) - } -} - -pub type AnEntity = Box<dyn Entity>; - -impl Positioned for AnEntity { - fn position(&self) -> Position { - (**self).position() - } -} - -impl PositionedMut for AnEntity { - fn set_position(&mut self, pos: Position) { - (**self).set_position(pos) - } -} diff --git a/src/entities/entity_char.rs b/src/entities/entity_char.rs deleted file mode 100644 index 70f26bfffdbd..000000000000 --- a/src/entities/entity_char.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::display::color::Color; -use std::fmt::{self, Display, Formatter}; -use termion::color; - -#[derive(Debug, Deserialize, PartialEq, Eq)] -pub struct EntityChar { - #[serde(default)] - color: Color, - - #[serde(rename = "char")] - chr: char, -} - -impl Display for EntityChar { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!( - f, - "{}{}{}", - color::Fg(&self.color), - self.chr, - color::Fg(color::Reset) - ) - } -} diff --git a/src/entities/environment.rs b/src/entities/environment.rs deleted file mode 100644 index 8f8a56706287..000000000000 --- a/src/entities/environment.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::display; -use crate::display::draw_box::{BoxStyle, Stylable}; -use crate::entities::Entity; -use crate::types::{Neighbors, Position}; -use std::io::{self, Write}; - -entity! { - pub struct Wall { - pub style: BoxStyle - } -} - -static_description!(Wall, "a wall"); - -impl Wall { - pub fn new(position: Position, style: BoxStyle) -> Self { - new_entity!(Wall { position, style }) - } -} - -impl display::DrawWithNeighbors for Wall { - fn do_draw_with_neighbors<'a, 'b>( - &'a self, - out: &'b mut dyn Write, - neighbors: &'a Neighbors<Vec<&'a Box<dyn Entity>>>, - ) -> io::Result<()> { - let neighbor_styles: Neighbors<Option<BoxStyle>> = - neighbors.map(|es| { - es.iter() - .filter_map(|e| e.downcast_ref::<Wall>()) - .map(|wall| wall.style) - .next() - }); - write!(out, "{}", neighbor_styles.style(self.style)) - } -} diff --git a/src/entities/item.rs b/src/entities/item.rs deleted file mode 100644 index 5f08780d4fb2..000000000000 --- a/src/entities/item.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::display; -use crate::entities::raws::{raw, EntityRaw, ItemType}; -use crate::entities::{Describe, EntityID}; -use crate::types::Position; -use std::io::{self, Write}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Item { - pub id: Option<EntityID>, - pub typ: &'static ItemType<'static>, - pub position: Position, -} - -impl Item { - pub fn new_from_raw(name: &'static str, position: Position) -> Self { - match raw(name) { - EntityRaw::Item(typ) => Self::new_with_type(typ, position), - _ => panic!("Invalid raw type for {:?}, expected Item", name), - } - } - - pub fn new_with_type( - typ: &'static ItemType<'static>, - position: Position, - ) -> Self { - Item { - id: None, - typ, - position, - } - } - - pub fn is_edible(&self) -> bool { - self.typ.is_edible() - } -} - -entity!(Item); - -impl Describe for Item { - fn description(&self) -> String { - self.typ.description.to_string() - } -} - -impl display::Draw for Item { - fn do_draw(&self, out: &mut dyn Write) -> io::Result<()> { - write!(out, "{}", self.typ.chr) - } -} diff --git a/src/entities/mod.rs b/src/entities/mod.rs deleted file mode 100644 index a8c39ed8aa78..000000000000 --- a/src/entities/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[macro_use] -pub mod entity; -#[macro_use] -pub mod util; -pub mod character; -pub mod creature; -pub mod entity_char; -pub mod environment; -pub mod item; -pub mod raw_types; -pub mod raws; - -pub use character::Character; -pub use creature::Creature; -pub use entity::{AnEntity, Describe, Entity, Identified}; -pub use entity_char::EntityChar; -pub use item::Item; -pub use raws::raw; - -pub type EntityID = u32; diff --git a/src/entities/raw_types.rs b/src/entities/raw_types.rs deleted file mode 100644 index 4bc291b69580..000000000000 --- a/src/entities/raw_types.rs +++ /dev/null @@ -1,110 +0,0 @@ -use crate::entities::entity_char::EntityChar; -use crate::messages::Message; -use crate::types::Speed; - -#[derive(Debug, Deserialize)] -pub struct CreatureType<'a> { - /// The name of the creature. Used in raw lookups. - pub name: &'a str, - - /// A description of the entity, used by the "look" command - pub description: &'a str, - - #[serde(rename = "char")] - pub chr: EntityChar, - pub max_hitpoints: u16, - pub speed: Speed, - pub friendly: bool, -} - -#[derive(Debug, Deserialize, PartialEq, Eq)] -pub struct EdibleItem<'a> { - #[serde(borrow)] - pub eat_message: Option<Message<'a>>, - - /// The number of hitpoints that eating this item heals - pub hitpoints_healed: u16, -} - -#[derive(Debug, Deserialize, PartialEq, Eq)] -pub struct ItemType<'a> { - pub name: &'a str, - - /// A description of the item, used by the "look" command and when walking - /// over the item on the ground - pub description: &'a str, - - /// A longer description of the item - pub long_description: &'a str, - - pub edible_item: Option<EdibleItem<'a>>, - - #[serde(rename = "char")] - pub chr: EntityChar, -} - -#[cfg(test)] -mod item_type_tests { - use super::*; - - #[test] - fn test_deserialize_item_type() { - let result = serde_json::from_str( - r#"{ - "Item": { - "name": "noodles", - "description": "a big bowl o' noodles", - "long_description": "You know exactly what kind of noodles", - "char": { "char": "n" }, - "edible_item": { - "eat_message": "You slurp up the noodles", - "hitpoints_healed": 2 - } - } - }"#, - ) - .unwrap(); - assert_matches!(result, EntityRaw::Item(_)); - if let EntityRaw::Item(item) = result { - assert_eq!(item.name, "noodles"); - } - - let toml_result = toml::from_str( - r#"[Item] -name = "noodles" -description = "a big bowl o' noodles" -long_description = "You know exactly what kind of noodles" -char = { char = "๐" } -edible_item = { eat_message = "You slurp up the noodles", hitpoints_healed = 2 } -"#, - ) - .unwrap(); - - assert_matches!(toml_result, EntityRaw::Item(_)); - if let EntityRaw::Item(item) = toml_result { - assert_eq!(item.name, "noodles"); - } - } -} - -impl<'a> ItemType<'a> { - pub fn is_edible(&self) -> bool { - self.edible_item.is_some() - } -} - -#[derive(Debug, Deserialize)] -pub enum EntityRaw<'a> { - Creature(#[serde(borrow)] CreatureType<'a>), - Item(#[serde(borrow)] ItemType<'a>), -} - -impl<'a> EntityRaw<'a> { - pub fn name(&self) -> &'a str { - use EntityRaw::*; - match self { - Creature(typ) => typ.name, - Item(typ) => typ.name, - } - } -} diff --git a/src/entities/raws.rs b/src/entities/raws.rs deleted file mode 100644 index 061e29a84037..000000000000 --- a/src/entities/raws.rs +++ /dev/null @@ -1,38 +0,0 @@ -pub use crate::entities::raw_types::{CreatureType, EntityRaw, ItemType}; -use std::collections::HashMap; - -static_cfg! { - static ref RAWS: Vec<EntityRaw<'static>> = cfg_dir("src/entities/raws"); -} - -lazy_static! { - static ref RAWS_BY_NAME: HashMap<&'static str, &'static EntityRaw<'static>> = { - let mut hm = HashMap::new(); - for er in RAWS.iter() { - if hm.contains_key(er.name()) { - panic!("Duplicate entity: {}", er.name()) - } - - hm.insert(er.name(), er); - } - hm - }; -} - -pub fn raw(name: &'static str) -> &'static EntityRaw<'static> { - RAWS_BY_NAME - .get(name) - .copied() - .unwrap_or_else(|| panic!("Raw not found: {}", name)) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_raws() { - RAWS_BY_NAME.keys(); - assert_eq!(raw("noodles").name(), "noodles"); - } -} diff --git a/src/entities/raws/gormlak.toml b/src/entities/raws/gormlak.toml deleted file mode 100644 index be30362d25bd..000000000000 --- a/src/entities/raws/gormlak.toml +++ /dev/null @@ -1,10 +0,0 @@ -[Creature] -name = "gormlak" -description = """ -A chittering imp-like creature with bright yellow horns. It adores shiny objects -and gathers in swarms. -""" -char = { char = "g", color = "red" } -max_hitpoints = 5 -speed = 120 -friendly = false diff --git a/src/entities/raws/noodles.json b/src/entities/raws/noodles.json deleted file mode 100644 index dfa2609f5ecb..000000000000 --- a/src/entities/raws/noodles.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "Item": { - "name": "noodles", - "char": { - "char": "n", - "color": "yellow" - }, - "description": "a big bowl o' noodles", - "long_description": "You know exactly what kind of noodles", - "edible_item": { - "eat_message": "You slurp up the noodles", - "hitpoints_healed": 2 - } - } -} diff --git a/src/entities/util.rs b/src/entities/util.rs deleted file mode 100644 index 6c11ffadf994..000000000000 --- a/src/entities/util.rs +++ /dev/null @@ -1,72 +0,0 @@ -#[macro_export] -macro_rules! new_entity { - ($name: ident) => { - new_entity!($name, {}) - }; - - ($name: ident { position: $position:expr $(, $fields:tt)* }) => { - $name { - id: None, - position: $position, - $($fields)* - } - }; - - ($name: ident { $position:expr $(, $fields:tt)* }) => { - $name { - id: None, - position: $position, - $($fields)* - } - }; -} - -#[macro_export] -macro_rules! boring_entity { - ($name:ident) => { - entity! { - pub struct $name {} - } - - impl $name { - #[allow(dead_code)] - pub fn new(position: $crate::types::Position) -> Self { - $name { id: None, position } - } - } - }; - - ($name:ident, char: $char: expr) => { - boring_entity!($name); - - impl $crate::display::Draw for $name { - fn do_draw(&self, out: &mut Write) -> io::Result<()> { - write!(out, "{}", $char) - } - } - }; -} - -#[macro_export] -macro_rules! entity { - ($name: ident) => { - positioned!($name); - positioned_mut!($name); - identified!($name, $crate::entities::EntityID); - impl $crate::entities::entity::Entity for $name {} - }; - - (pub struct $name:ident { $($struct_contents:tt)* } $($rest:tt)*) => { - #[derive(Debug, PartialEq, Eq, Clone)] - pub struct $name { - pub id: Option<$crate::entities::EntityID>, - pub position: $crate::types::Position, - $($struct_contents)* - } - - entity!($name); - entity!($($rest)*); - }; - - () => {}; -} diff --git a/src/game.rs b/src/game.rs deleted file mode 100644 index c478e0d2f55b..000000000000 --- a/src/game.rs +++ /dev/null @@ -1,617 +0,0 @@ -use crate::description::list_to_sentence; -use crate::display::{self, Viewport}; -use crate::entities::entity::Describe; -use crate::entities::entity::Entity; -use crate::entities::{ - AnEntity, Character, Creature, EntityID, Identified, Item, -}; -use crate::messages::message; -use crate::settings::Settings; -use crate::types::command::Command; -use crate::types::entity_map::EntityMap; -use crate::types::{ - pos, BoundingBox, Collision, Dimensions, Position, Positioned, Ticks, -}; -use crate::util::promise::Cancelled; -use crate::util::promise::{promise, Complete, Promise, Promises}; -use crate::util::template::TemplateParams; -use rand::rngs::SmallRng; -use rand::SeedableRng; -use std::io::{self, StdinLock, StdoutLock, Write}; -use termion::input::Keys; -use termion::input::TermRead; -use termion::raw::RawTerminal; - -type Stdout<'a> = RawTerminal<StdoutLock<'a>>; - -type Rng = SmallRng; - -enum PromptResolution { - Uncancellable(Complete<String>), - Cancellable(Complete<Result<String, Cancelled>>), -} - -/// The mode to use when describing entities on a tile to the user -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -enum EntityDescriptionMode { - /// Describe the entities that the user is walking over. - /// - /// This means: - /// - Skip the character themselves - /// - Describe nothing if there are no items other than the character - Walk, - - /// Describe entities that the user is actively asking about. - /// - /// This means: - /// - Describe the character themselves if they've asked to look at the tile - /// they're standing on - /// - Explicitly say there's nothing there if there's nothing there. - Look, -} - -impl PromptResolution { - fn is_cancellable(&self) -> bool { - use PromptResolution::*; - match self { - Uncancellable(_) => false, - Cancellable(_) => true, - } - } - - fn fulfill(&mut self, val: String) { - use PromptResolution::*; - match self { - Cancellable(complete) => complete.ok(val), - Uncancellable(complete) => complete.fulfill(val), - } - } - - fn cancel(&mut self) { - use PromptResolution::*; - match self { - Cancellable(complete) => complete.cancel(), - Uncancellable(_complete) => {} - } - } -} - -/// The kind of input the game is waiting to receive -enum InputState { - /// The initial input state of the game - we're currently waiting for direct - /// commands. - Initial, - - /// A free text prompt has been shown to the user, and every character - /// besides "escape" is interpreted as a response to that prompt - Prompt { - complete: PromptResolution, - buffer: String, - }, -} - -impl InputState { - fn uncancellable_prompt(complete: Complete<String>) -> Self { - InputState::Prompt { - complete: PromptResolution::Uncancellable(complete), - buffer: String::new(), - } - } - - fn cancellable_prompt( - complete: Complete<Result<String, Cancelled>>, - ) -> Self { - InputState::Prompt { - complete: PromptResolution::Cancellable(complete), - buffer: String::new(), - } - } -} - -impl Default for InputState { - fn default() -> Self { - InputState::Initial - } -} - -/// The full state of a running Game -pub struct Game<'a> { - settings: Settings, - - viewport: Viewport<Stdout<'a>>, - - /// An iterator on keypresses from the user - keys: Keys<StdinLock<'a>>, - - /// The kind of input the game is waiting to receive - input_state: InputState, - - /// The map of all the entities in the game - entities: EntityMap<AnEntity>, - - /// The entity ID of the player character - character_entity_id: EntityID, - - /// The messages that have been said to the user, in forward time order - messages: Vec<String>, - - /// The index of the currently-displayed message. Used to track the index of - /// the currently displayed message when handling PreviousMessage commands - message_idx: usize, - - /// A global random number generator for the game - rng: Rng, - - /// A list of promises that are waiting on the game and a result - promises: Promises<'a, Self>, -} - -impl<'a> Game<'a> { - pub fn new( - settings: Settings, - stdout: RawTerminal<StdoutLock<'a>>, - stdin: StdinLock<'a>, - w: u16, - h: u16, - ) -> Game<'a> { - let rng = match settings.seed { - Some(seed) => SmallRng::seed_from_u64(seed), - None => SmallRng::from_entropy(), - }; - let mut entities: EntityMap<AnEntity> = EntityMap::new(); - - // TODO make this dynamic - { - entities.insert(Box::new(Creature::new_from_raw( - "gormlak", - pos(10, 0), - ))); - - entities - .insert(Box::new(Item::new_from_raw("noodles", pos(0, 10)))); - } - - Game { - settings, - rng, - message_idx: 0, - viewport: Viewport::new( - BoundingBox::at_origin(Dimensions { w, h }), - BoundingBox::at_origin(Dimensions { w: w - 2, h: h - 2 }), - stdout, - ), - keys: stdin.keys(), - input_state: Default::default(), - character_entity_id: entities.insert(Box::new(Character::new())), - messages: Vec::new(), - entities, - promises: Promises::new(), - } - } - - fn downcast_entities_at<A: Entity>(&self, pos: Position) -> Vec<&A> { - self.entities - .at(pos) - .iter() - .filter_map(|e| e.downcast_ref()) - .collect() - } - - /// Returns a list of all creature entities at the given position - fn creatures_at(&self, pos: Position) -> Vec<&Creature> { - self.downcast_entities_at(pos) - } - - /// Returns a list of all item entities at the given position - fn items_at(&self, pos: Position) -> Vec<&Item> { - self.downcast_entities_at(pos) - } - - /// Returns a collision, if any, at the given Position in the game - fn collision_at(&self, pos: Position) -> Option<Collision> { - if !pos.within(self.viewport.inner) { - Some(Collision::Stop) - } else if self.creatures_at(pos).is_empty() { - None - } else { - Some(Collision::Combat) - } - } - - fn character(&self) -> &Character { - (*self.entities.get(self.character_entity_id).unwrap()) - .downcast_ref() - .unwrap() - } - - fn mut_character(&mut self) -> &mut Character { - (*self.entities.get_mut(self.character_entity_id).unwrap()) - .downcast_mut() - .unwrap() - } - - /// Draw all the game entities to the screen - fn draw_entities(&mut self) -> io::Result<()> { - for entity in self.entities.entities() { - self.viewport.draw( - entity, - &self.entities.neighbor_entities(entity.position()), - )?; - } - Ok(()) - } - - /// Draw all the game entities to the screen - fn draw_entities_at(&mut self, pos: Position) -> io::Result<()> { - for entity in self.entities.at(pos) { - self.viewport.draw( - entity, - &self.entities.neighbor_entities(entity.position()), - )?; - } - Ok(()) - } - - /// Draw the game entity with the given ID, if any, to the screen - fn draw_entity(&mut self, entity_id: EntityID) -> io::Result<bool> { - if let Some(entity) = self.entities.get(entity_id) { - self.viewport.draw( - entity, - &self.entities.neighbor_entities(entity.position()), - )?; - Ok(true) - } else { - Ok(false) - } - } - - /// Describe all the entities at a given position to the user. - /// - /// If `force` is not set to `true`, will not do anything if there are no - /// entities - fn describe_entities_at( - &mut self, - pos: Position, - mode: EntityDescriptionMode, - ) -> io::Result<()> { - use EntityDescriptionMode::*; - let mut entities = self.entities.at(pos); - if mode == Walk { - entities.retain(|e| e.id() != self.character_entity_id); - } - - if entities.is_empty() { - match mode { - Walk => return Ok(()), - Look => { - return self.say( - "global.describe_no_entities", - &template_params!(), - ) - } - } - } - - let descriptions = list_to_sentence( - &entities - .iter() - .map(|e| e.description()) - .collect::<Vec<String>>(), - ); - - self.say( - "global.describe_entities", - &template_params!({ "descriptions" => &descriptions, }), - ) - } - - /// Remove the given entity from the game, drawing over it if it's visible - fn remove_entity(&mut self, entity_id: EntityID) -> io::Result<()> { - if let Some(entity) = self.entities.remove(entity_id) { - self.viewport.clear(entity.position())?; - } - Ok(()) - } - - /// Step the game forward the given number of ticks - fn tick(&mut self, _ticks: Ticks) {} - - /// Get a message from the global map based on the rng in this game - fn message<'params>( - &mut self, - name: &'static str, - params: &TemplateParams<'params>, - ) -> String { - message(name, &mut self.rng, params) - } - - /// Say a message to the user - fn say<'params>( - &mut self, - message_name: &'static str, - params: &TemplateParams<'params>, - ) -> io::Result<()> { - let message = self.message(message_name, params); - self.messages.push(message.to_string()); - self.message_idx = self.messages.len() - 1; - self.viewport.write_message(&message)?; - Ok(()) - } - - /// Prompt the user for input, returning a Future for the result of the - /// prompt - fn prompt( - &mut self, - name: &'static str, - params: &TemplateParams<'_>, - ) -> io::Result<Promise<Self, String>> { - let (complete, promise) = promise(); - self.input_state = InputState::uncancellable_prompt(complete); - let message = self.message(name, params); - self.viewport.write_prompt(&message)?; - self.promises.push(Box::new(promise.clone())); - Ok(promise) - } - - fn prompt_cancellable( - &mut self, - name: &'static str, - params: &TemplateParams<'_>, - ) -> io::Result<Promise<Self, Result<String, Cancelled>>> { - let (complete, promise) = promise(); - self.input_state = InputState::cancellable_prompt(complete); - let message = self.message(name, params); - self.viewport.write_prompt(&message)?; - self.promises.push(Box::new(promise.clone())); - Ok(promise) - } - - fn previous_message(&mut self) -> io::Result<()> { - if self.message_idx == 0 { - return Ok(()); - } - self.message_idx -= 1; - let message = &self.messages[self.message_idx]; - self.viewport.write_message(message)?; - Ok(()) - } - - fn clear_message(&mut self) -> io::Result<()> { - debug!("{:?} {:?}", self.message_idx, self.messages); - if self.message_idx == self.messages.len() { - return Ok(()); - } - self.viewport.clear_message()?; - self.message_idx += 1; - Ok(()) - } - - fn creature(&self, creature_id: EntityID) -> Option<&Creature> { - self.entities - .get(creature_id) - .and_then(|e| e.downcast_ref::<Creature>()) - } - - fn expect_creature(&self, creature_id: EntityID) -> &Creature { - self.creature(creature_id).unwrap_or_else(|| { - panic!("Creature ID went away: {:?}", creature_id) - }) - } - - fn mut_creature(&mut self, creature_id: EntityID) -> Option<&mut Creature> { - self.entities - .get_mut(creature_id) - .and_then(|e| e.downcast_mut::<Creature>()) - } - - fn expect_mut_creature(&mut self, creature_id: EntityID) -> &mut Creature { - self.mut_creature(creature_id).unwrap_or_else(|| { - panic!("Creature ID went away: {:?}", creature_id) - }) - } - - fn attack(&mut self, creature_id: EntityID) -> io::Result<()> { - info!("Attacking creature {:?}", creature_id); - let damage = self.character().damage(); - let creature_name = self.expect_creature(creature_id).typ.name; - let tps = template_params!({ - "creature" => { - "name" => creature_name, - }, - }); - self.say("combat.attack", &tps)?; - - let creature = self.expect_mut_creature(creature_id); - creature.damage(damage); - if creature.dead() { - self.say("combat.killed", &tps)?; - info!("Killed creature {:?}", creature_id); - self.remove_entity(creature_id)?; - } - Ok(()) - } - - fn attack_at(&mut self, pos: Position) -> io::Result<()> { - let creatures = self.creatures_at(pos); - match creatures.len() { - 0 => Ok(()), - 1 => { - let creature = creatures.get(0).unwrap(); - let creature_id = creature.id(); - self.attack(creature_id) - } - _ => { - // TODO prompt with a menu of creatures to combat - unimplemented!() - } - } - } - - fn pick_up(&mut self) -> io::Result<()> { - let pos = self.character().position; - let items = self.items_at(pos); - match items.len() { - 0 => Ok(()), - 1 => { - let item_id = items.get(0).unwrap().id(); - let item: Box<Item> = - self.entities.remove(item_id).unwrap().downcast().unwrap(); - let desc = item.description(); - self.mut_character().inventory.push(item); - self.say( - "global.pick_up", - &template_params!({ - "item" => { "name" => &desc, }, - }), - ) - } - _ => { - // TODO prompt with a menu of items to pick up - unimplemented!() - } - } - } - - fn flush_promises(&mut self) { - unsafe { - let game = self as *mut Self; - (*game).promises.give_all(&mut *game); - } - } - - /// Run the game - pub fn run(mut self) -> io::Result<()> { - info!("Running game"); - self.viewport.init()?; - self.draw_entities()?; - self.flush().unwrap(); - - self.prompt("character.name_prompt", &template_params!())? - .on_fulfill(|game, char_name| { - game.say( - "global.welcome", - &template_params!({ - "character" => { - "name" => char_name, - }, - }), - ) - .unwrap(); - game.flush().unwrap(); - game.mut_character().set_name(char_name.to_string()); - }); - - loop { - let mut old_position = None; - let next_key = self.keys.next().unwrap().unwrap(); - match &mut self.input_state { - InputState::Initial => { - use Command::*; - match Command::from_key(next_key) { - Some(Quit) => { - info!("Quitting game due to user request"); - break; - } - - Some(Move(direction)) => { - use Collision::*; - let new_pos = self.character().position + direction; - match self.collision_at(new_pos) { - None => { - old_position = - Some(self.character().position); - self.entities.update_position( - self.character_entity_id, - new_pos, - ); - } - Some(Combat) => { - self.attack_at(new_pos)?; - } - Some(Stop) => (), - } - } - - Some(PreviousMessage) => self.previous_message()?, - - Some(PickUp) => self.pick_up()?, - - None => (), - } - - if let Some(old_pos) = old_position { - let character = self.character(); - let char_pos = character.position; - self.viewport.game_cursor_position = char_pos; - self.viewport.clear(old_pos)?; - self.draw_entities_at(old_pos)?; - self.draw_entity(self.character_entity_id)?; - self.clear_message()?; - self.describe_entities_at( - char_pos, - EntityDescriptionMode::Walk, - )?; - self.tick( - self.character().speed().tiles_to_ticks( - (old_pos - char_pos).as_tiles(), - ), - ); - } - } - - InputState::Prompt { complete, buffer } => { - use termion::event::Key::*; - match next_key { - Char('\n') => { - info!("Prompt complete: \"{}\"", buffer); - self.viewport.clear_prompt()?; - complete.fulfill(buffer.clone()); - self.input_state = InputState::Initial; - } - Char(chr) => { - buffer.push(chr); - self.viewport.push_prompt_chr(chr)?; - } - Esc => complete.cancel(), - Backspace => { - buffer.pop(); - self.viewport.pop_prompt_chr()?; - } - _ => {} - } - } - } - - self.flush()?; - self.flush_promises(); - debug!("{:?}", self.character()); - } - Ok(()) - } -} - -impl<'a> Drop for Game<'a> { - fn drop(&mut self) { - display::clear(self).unwrap_or(()); - } -} - -impl<'a> Write for Game<'a> { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - self.viewport.write(buf) - } - - fn flush(&mut self) -> io::Result<()> { - self.viewport.flush() - } - - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - self.viewport.write_all(buf) - } -} - -impl<'a> Positioned for Game<'a> { - fn position(&self) -> Position { - Position { x: 0, y: 0 } - } -} diff --git a/src/level_gen/cave_automata.rs b/src/level_gen/cave_automata.rs deleted file mode 100644 index e5e2807ab251..000000000000 --- a/src/level_gen/cave_automata.rs +++ /dev/null @@ -1,120 +0,0 @@ -use crate::level_gen::util::fill_outer_edges; -use crate::level_gen::util::rand_initialize; -use crate::types::Dimensions; -use rand::Rng; - -pub struct Params { - chance_to_start_alive: f64, - birth_limit: i32, - death_limit: i32, - steps: usize, -} - -macro_rules! parse_optional { - ($out: ident . $attr: ident, $matches: expr, $arg: expr) => { - if let Some(val_s) = $matches.value_of($arg) { - $out.$attr = val_s.parse().unwrap(); - } - }; -} - -macro_rules! parse_optional_matches { - ($matches: expr) => {}; - ($matches: expr , { $ret: ident . $attr: ident = $arg: expr }) => { - parse_optional!($ret.$attr, $matches, $arg); - }; - ($matches: expr, { $($ret: ident . $attr: ident = $arg: expr ,)* }) => { - $(parse_optional!($ret.$attr, $matches, $arg);)* - }; -} - -impl Params { - pub fn from_matches<'a>(matches: &clap::ArgMatches<'a>) -> Self { - let mut ret: Self = Default::default(); - parse_optional_matches!(matches, { - ret.chance_to_start_alive = "start-alive-chance", - ret.birth_limit = "birth-limit", - ret.death_limit = "death-limit", - ret.steps = "steps", - }); - ret - } -} - -impl Default for Params { - fn default() -> Self { - Params { - chance_to_start_alive: 0.45, - birth_limit: 4, - death_limit: 3, - steps: 2, - } - } -} - -pub fn generate<R: Rng + ?Sized>( - dimensions: Dimensions, - params: &Params, - rand: &mut R, -) -> Vec<Vec<bool>> { - let mut cells = - rand_initialize(dimensions, rand, params.chance_to_start_alive); - for _ in 0..params.steps { - step_automata(&mut cells, dimensions, params); - } - - fill_outer_edges(&mut cells); - - cells -} - -fn step_automata( - cells: &mut Vec<Vec<bool>>, - dimensions: Dimensions, - params: &Params, -) { - let orig_cells = (*cells).clone(); - for x in 0..(dimensions.h as usize) { - for y in 0..(dimensions.w as usize) { - let nbs = num_alive_neighbors(&orig_cells, x as i32, y as i32); - if orig_cells[x][y] { - if nbs < params.death_limit { - cells[x][y] = false; - } else { - cells[x][y] = true; - } - } else if nbs > params.birth_limit { - cells[x][y] = true; - } else { - cells[x][y] = false; - } - } - } -} - -const COUNT_EDGES_AS_NEIGHBORS: bool = true; - -fn num_alive_neighbors(cells: &[Vec<bool>], x: i32, y: i32) -> i32 { - let mut count = 0; - for i in -1..2 { - for j in -1..2 { - if i == 0 && j == 0 { - continue; - } - - let neighbor_x = x + i; - let neighbor_y = y + j; - - if (COUNT_EDGES_AS_NEIGHBORS - && (neighbor_x < 0 - || neighbor_y < 0 - || neighbor_x >= (cells.len() as i32) - || neighbor_y >= (cells[0].len()) as i32)) - || cells[neighbor_x as usize][neighbor_y as usize] - { - count += 1; - } - } - } - count -} diff --git a/src/level_gen/mod.rs b/src/level_gen/mod.rs deleted file mode 100644 index d796a103b11e..000000000000 --- a/src/level_gen/mod.rs +++ /dev/null @@ -1,101 +0,0 @@ -use crate::display::draw_box::BoxStyle; -use crate::display::utils::clone_times; -use crate::display::DrawWithNeighbors; -use crate::entities::entity::Entity; -use crate::entities::environment::Wall; -use crate::types::entity_map::EntityMap; -use crate::types::pos; -use itertools::Itertools; -use std::io; - -pub mod cave_automata; -pub mod util; - -pub fn level_to_entities(level: Vec<Vec<bool>>) -> EntityMap<Box<dyn Entity>> { - let mut res: EntityMap<Box<dyn Entity>> = EntityMap::new(); - - let xmax = level.len() as i16; - let ymax = if xmax == 0 { - 0i16 - } else { - level[0].len() as i16 - }; - - let get = |mut x: i16, mut y: i16| { - if x < 0 { - x = 0; - } - if y < 0 { - y = 0; - } - if x >= xmax - 1 { - x = xmax - 1; - } - if y >= ymax - 1 { - y = ymax - 1; - } - level[x as usize][y as usize] - }; - - for x in 0..xmax { - for y in 0..ymax { - if get(x, y) { - // don't output walls that are surrounded on all 8 sides by - // walls - if (x == 0 || get(x - 1, y)) - && (y == 0 || get(x, y - 1)) - && (x == xmax - 1 || get(x + 1, y)) - && (y == ymax - 1 || get(x, y + 1)) - && ((x == 0 && y == 0) || get(x - 1, y - 1)) - && ((x == 0 && y == ymax - 1) || get(x - 1, y + 1)) - && ((x == xmax - 1 && y == 0) || get(x + 1, y - 1)) - && ((x == xmax - 1 && y == ymax - 1) || get(x + 1, y + 1)) - { - continue; - } - res.insert(Box::new(Wall::new( - pos(y as i16, x as i16), - BoxStyle::Thin, - ))); - } - } - } - - res -} - -pub fn draw_level<W: io::Write>( - level: Vec<Vec<bool>>, - out: &mut W, -) -> io::Result<()> { - if level.is_empty() { - return Ok(()); - } - - let mut lines = clone_times::<Vec<char>, Vec<Vec<char>>>( - clone_times(' ', level[0].len() as u16), - level.len() as u16, - ); - - let em = level_to_entities(level); - - for entity in em.entities() { - let mut buf = Vec::new(); - entity.do_draw_with_neighbors( - &mut buf, - &em.neighbor_entities(entity.position()), - )?; - let buf_s = std::str::from_utf8(&buf).unwrap(); - if let Some(chr) = buf_s.chars().next() { - lines[entity.position().y as usize][entity.position().x as usize] = - chr; - } - } - - let res = lines - .iter() - .map(|line| line.iter().collect::<String>()) - .join("\n"); - - write!(out, "{}", res) -} diff --git a/src/level_gen/util.rs b/src/level_gen/util.rs deleted file mode 100644 index 4f56fe6c9557..000000000000 --- a/src/level_gen/util.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::types::Dimensions; -use rand::{distributions, Rng}; - -pub fn falses(dims: Dimensions) -> Vec<Vec<bool>> { - let mut ret = Vec::with_capacity(dims.h as usize); - for _ in 0..dims.h { - let mut row = Vec::with_capacity(dims.w as usize); - for _ in 0..dims.w { - row.push(false); - } - ret.push(row); - } - ret -} - -/// Randomly initialize a 2-dimensional boolean vector of the given -/// `Dimensions`, using the given random number generator and alive chance -pub fn rand_initialize<R: Rng + ?Sized>( - dims: Dimensions, - rng: &mut R, - alive_chance: f64, -) -> Vec<Vec<bool>> { - let distrib = distributions::Bernoulli::new(alive_chance).unwrap(); - let mut ret = Vec::with_capacity(dims.h as usize); - for _ in 0..dims.h { - let mut row = Vec::with_capacity(dims.w as usize); - for _ in 0..dims.w { - row.push(rng.sample(distrib)); - } - ret.push(row); - } - ret -} - -/// Fill the outer edges of a generated level with walls -pub fn fill_outer_edges(level: &mut Vec<Vec<bool>>) { - let xmax = level.len(); - if xmax == 0 { - return; - } - let ymax = level[0].len(); - - for row in level.iter_mut() { - row[0] = true; - row[ymax - 1] = true; - } - - for y in 0..level[0].len() { - level[0][y] = true; - level[xmax - 1][y] = true; - } -} diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 8004a5739ef5..000000000000 --- a/src/main.rs +++ /dev/null @@ -1,130 +0,0 @@ -#[macro_use] -extern crate log; -#[macro_use] -extern crate serde_derive; -#[macro_use] -extern crate clap; -#[macro_use] -extern crate prettytable; -#[macro_use] -extern crate lazy_static; -#[cfg(test)] -#[macro_use] -extern crate maplit; -#[macro_use] -extern crate downcast_rs; -#[macro_use] -extern crate include_dir; -#[macro_use] -extern crate nom; -#[cfg(test)] -#[macro_use] -extern crate matches; - -#[macro_use] -mod util; -#[macro_use] -mod types; -#[macro_use] -mod entities; -mod description; -mod display; -mod game; -mod level_gen; -mod messages; -mod settings; - -use crate::types::Dimensions; -use clap::App; -use game::Game; -use prettytable::format::consts::FORMAT_BOX_CHARS; -use rand::rngs::SmallRng; -use rand::SeedableRng; -use settings::Settings; - -use backtrace::Backtrace; -use std::io::{self, StdinLock, StdoutLock}; -use std::panic; - -use termion; -use termion::raw::IntoRawMode; -use termion::raw::RawTerminal; - -fn init( - settings: Settings, - stdout: RawTerminal<StdoutLock<'_>>, - stdin: StdinLock<'_>, - w: u16, - h: u16, -) -> io::Result<()> { - panic::set_hook(if settings.logging.print_backtrace { - Box::new(|info| (error!("{}\n{:#?}", info, Backtrace::new()))) - } else { - Box::new(|info| (error!("{}\n{:#?}", info, Backtrace::new()))) - }); - - let game = Game::new(settings, stdout, stdin, w, h); - game.run() -} - -fn generate_level<'a, W: io::Write>( - stdout: &mut W, - params: &clap::ArgMatches<'a>, -) -> io::Result<()> { - let mut rand = SmallRng::from_entropy(); - - let mut dimensions: Dimensions = Default::default(); - if let Some(h_s) = params.value_of("height") { - dimensions.h = h_s.parse().unwrap(); - } - if let Some(w_s) = params.value_of("width") { - dimensions.w = w_s.parse().unwrap(); - } - - let level = match params.value_of("generator") { - None => panic!("Must supply a generator with --generator"), - Some("cave_automata") => level_gen::cave_automata::generate( - dimensions, - &level_gen::cave_automata::Params::from_matches(params), - &mut rand, - ), - Some(gen) => panic!("Unrecognized generator: {}", gen), - }; - level_gen::draw_level(level, stdout) -} - -fn main() -> io::Result<()> { - let yaml = load_yaml!("cli.yml"); - let matches = App::from_yaml(yaml).get_matches(); - let settings = Settings::load().unwrap(); - settings.logging.init_log(); - let stdout = io::stdout(); - let mut stdout = stdout.lock(); - - let stdin = io::stdin(); - let stdin = stdin.lock(); - - let termsize = termion::terminal_size().ok(); - let (termwidth, termheight) = termsize.unwrap_or((70, 40)); - - match matches.subcommand() { - ("info", _) => { - let mut table = table!( - [br->"termwidth", termwidth], - [br->"termheight", termheight], - [br->"logfile", settings.logging.file], - [br->"loglevel", settings.logging.level] - ); - table.set_format(*FORMAT_BOX_CHARS); - table.printstd(); - Ok(()) - } - ("generate-level", params) => { - generate_level(&mut stdout, params.unwrap()) - } - _ => { - let stdout = stdout.into_raw_mode().unwrap(); - init(settings, stdout, stdin, termwidth, termheight) - } - } -} diff --git a/src/messages.rs b/src/messages.rs deleted file mode 100644 index b081389efc9d..000000000000 --- a/src/messages.rs +++ /dev/null @@ -1,166 +0,0 @@ -use crate::util::template::Template; -use crate::util::template::TemplateParams; -use rand::seq::SliceRandom; -use rand::Rng; -use std::collections::HashMap; - -#[derive(Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -pub enum Message<'a> { - #[serde(borrow)] - Single(Template<'a>), - Choice(Vec<Template<'a>>), -} - -impl<'a> Message<'a> { - fn resolve<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<&Template<'a>> { - use Message::*; - match self { - Single(msg) => Some(msg), - Choice(msgs) => msgs.choose(rng), - } - } -} - -#[derive(Deserialize, Debug, PartialEq, Eq)] -#[serde(untagged)] -enum NestedMap<'a> { - #[serde(borrow)] - Direct(Message<'a>), - #[serde(borrow)] - Nested(HashMap<&'a str, NestedMap<'a>>), -} - -impl<'a> NestedMap<'a> { - fn lookup(&'a self, path: &str) -> Option<&'a Message<'a>> { - use NestedMap::*; - let leaf = - path.split('.') - .fold(Some(self), |current, key| match current { - Some(Nested(m)) => m.get(key), - _ => None, - }); - match leaf { - Some(Direct(msg)) => Some(msg), - _ => None, - } - } -} - -#[cfg(test)] -mod nested_map_tests { - use super::*; - - #[test] - fn test_deserialize_nested_map() { - let src = r#" -[global] -hello = "Hello World!" - -[foo.bar] -single = "Single" -choice = ["Say this", "Or this"] -"#; - let result = toml::from_str(src); - assert_eq!( - result, - Ok(NestedMap::Nested(hashmap! { - "global" => NestedMap::Nested(hashmap!{ - "hello" => NestedMap::Direct(Message::Single(Template::parse("Hello World!").unwrap())), - }), - "foo" => NestedMap::Nested(hashmap!{ - "bar" => NestedMap::Nested(hashmap!{ - "single" => NestedMap::Direct(Message::Single( - Template::parse("Single").unwrap() - )), - "choice" => NestedMap::Direct(Message::Choice( - vec![ - Template::parse("Say this").unwrap(), - Template::parse("Or this").unwrap() - ] - )) - }) - }) - })) - ) - } - - #[test] - fn test_lookup() { - let map: NestedMap<'static> = toml::from_str( - r#" -[global] -hello = "Hello World!" - -[foo.bar] -single = "Single" -choice = ["Say this", "Or this"] -"#, - ) - .unwrap(); - - assert_eq!( - map.lookup("global.hello"), - Some(&Message::Single(Template::parse("Hello World!").unwrap())) - ); - assert_eq!( - map.lookup("foo.bar.single"), - Some(&Message::Single(Template::parse("Single").unwrap())) - ); - assert_eq!( - map.lookup("foo.bar.choice"), - Some(&Message::Choice(vec![ - Template::parse("Say this").unwrap(), - Template::parse("Or this").unwrap() - ])) - ); - } -} - -// static MESSAGES_RAW: &'static str = include_str!("messages.toml"); - -static_cfg! { - static ref MESSAGES: NestedMap<'static> = toml_file("messages.toml"); -} - -pub fn get<R: Rng + ?Sized>( - name: &'static str, - rng: &mut R, -) -> Option<&'static Template<'static>> { - MESSAGES.lookup(name).and_then(|msg| msg.resolve(rng)) -} - -/// Look up and format a game message based on the given (dot-separated) name, -/// with the given random generator used to select from choice-based messages -pub fn message<'a, R: Rng + ?Sized>( - name: &'static str, - rng: &mut R, - params: &TemplateParams<'a>, -) -> String { - match get(name, rng) { - Some(msg) => msg.format(params).unwrap_or_else(|e| { - error!("Error formatting template: {}", e); - "Template Error".to_string() - }), - None => { - error!("Message not found: {}", name); - "Template Not Found".to_string() - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use rand::rngs::SmallRng; - use rand::SeedableRng; - - #[test] - fn test_static_messages() { - message( - "global.welcome", - &mut SmallRng::from_entropy(), - &template_params!(), - ); - } -} diff --git a/src/messages.toml b/src/messages.toml deleted file mode 100644 index a9a6b2e009a6..000000000000 --- a/src/messages.toml +++ /dev/null @@ -1,27 +0,0 @@ -[global] -welcome = "Welcome to Xanthous, {{character.name}}! It's dangerous out there, why not stay inside?" -describe_entities = "You see here {{descriptions}}" -describe_no_entities = "You see nothing here." -pick_up = "You pick up the {{item.name}}." - -[combat] -attack = "You attack the {{creature.name}}." -killed = [ - "You've killed the {{creature.name}}.", - "The {{creature.name}} dies.", - "The {{creature.name}} kicks it.", - "The {{creature.name}} beefs it." - ] - -[character] -name_prompt = [ - "Hey there friend. What's your name?", - "Hey there friend. What should we call you?", - "Howdy. What's your name?", - "Name please!", - "What's your name?", - "Hey, what's your name?", -] - -[defaults.item] -eat = "You eat the {{item.name}}. {{action.result}}" diff --git a/src/settings.rs b/src/settings.rs deleted file mode 100644 index 1f205814d1dd..000000000000 --- a/src/settings.rs +++ /dev/null @@ -1,70 +0,0 @@ -use config::{Config, ConfigError}; -use log::LevelFilter; -use log4rs::append::file::FileAppender; -use log4rs::config::{Appender, Root}; -use log4rs::encode::pattern::PatternEncoder; - -#[derive(Debug, Deserialize, Clone)] -pub struct Logging { - #[serde(default = "Logging::default_level")] - pub level: LevelFilter, - - #[serde(default = "Logging::default_file")] - pub file: String, - - #[serde(default = "Logging::default_print_backtrace")] - pub print_backtrace: bool, -} - -impl Default for Logging { - fn default() -> Self { - Logging { - level: LevelFilter::Off, - file: "debug.log".to_string(), - print_backtrace: true, - } - } -} - -impl Logging { - pub fn init_log(&self) { - let logfile = FileAppender::builder() - .encoder(Box::new(PatternEncoder::new("{d} {l} - {m}\n"))) - .build(self.file.clone()) - .unwrap(); - - let config = log4rs::config::Config::builder() - .appender(Appender::builder().build("logfile", Box::new(logfile))) - .build(Root::builder().appender("logfile").build(self.level)) - .unwrap(); - - log4rs::init_config(config).unwrap(); - } - - fn default_level() -> LevelFilter { - Logging::default().level - } - - fn default_file() -> String { - Logging::default().file - } - - fn default_print_backtrace() -> bool { - Logging::default().print_backtrace - } -} - -#[derive(Debug, Deserialize, Clone)] -pub struct Settings { - pub seed: Option<u64>, - pub logging: Logging, -} - -impl Settings { - pub fn load() -> Result<Self, ConfigError> { - let mut s = Config::new(); - s.merge(config::File::with_name("Config").required(false))?; - s.merge(config::Environment::with_prefix("XAN"))?; - s.try_into() - } -} diff --git a/src/types/collision.rs b/src/types/collision.rs deleted file mode 100644 index 59c60e69ee50..000000000000 --- a/src/types/collision.rs +++ /dev/null @@ -1,9 +0,0 @@ -/// Describes a kind of game collision -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Collision { - /// Stop moving - you can't move there! - Stop, - - /// Moving into an entity at the given position indicates combat - Combat, -} diff --git a/src/types/command.rs b/src/types/command.rs deleted file mode 100644 index 17ca4d280fd8..000000000000 --- a/src/types/command.rs +++ /dev/null @@ -1,41 +0,0 @@ -use super::Direction; -use super::Direction::*; -use termion::event::Key; -use termion::event::Key::{Char, Ctrl}; - -pub enum Command { - /// Quit the game - Quit, - - /// Move the character in a direction - Move(Direction), - - /// Pick up any item(s) at the current position - PickUp, - - /// Display the previous message - PreviousMessage, -} - -impl Command { - pub fn from_key(k: Key) -> Option<Command> { - use Command::*; - match k { - Char('q') => Some(Quit), - - Char('h') | Char('a') | Key::Left => Some(Move(Left)), - Char('k') | Char('w') | Key::Up => Some(Move(Up)), - Char('j') | Char('s') | Key::Down => Some(Move(Down)), - Char('l') | Char('d') | Key::Right => Some(Move(Right)), - Char('y') => Some(Move(UpLeft)), - Char('u') => Some(Move(UpRight)), - Char('b') => Some(Move(DownLeft)), - Char('n') => Some(Move(DownRight)), - - Ctrl('p') => Some(PreviousMessage), - Char(',') => Some(PickUp), - - _ => None, - } - } -} diff --git a/src/types/direction.rs b/src/types/direction.rs deleted file mode 100644 index 9b5c0991da8d..000000000000 --- a/src/types/direction.rs +++ /dev/null @@ -1,13 +0,0 @@ -use proptest_derive::Arbitrary; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -pub enum Direction { - Left, - Up, - Down, - Right, - UpLeft, - UpRight, - DownRight, - DownLeft, -} diff --git a/src/types/entity_map.rs b/src/types/entity_map.rs deleted file mode 100644 index 202d8b593e15..000000000000 --- a/src/types/entity_map.rs +++ /dev/null @@ -1,430 +0,0 @@ -use crate::entities::entity::Identified; -use crate::entities::EntityID; -use crate::types::Neighbors; -use crate::types::Position; -use crate::types::Positioned; -use crate::types::PositionedMut; -use alga::general::{ - AbstractMagma, AbstractMonoid, AbstractSemigroup, Additive, Identity, -}; -use std::collections::{hash_map, BTreeMap, HashMap}; -use std::iter::FromIterator; - -#[derive(Debug, Clone, Default)] -pub struct EntityMap<A> { - by_position: BTreeMap<Position, Vec<EntityID>>, - by_id: HashMap<EntityID, A>, - last_id: EntityID, -} - -impl<A: PartialEq> PartialEq for EntityMap<A> { - fn eq(&self, other: &Self) -> bool { - self.by_position == other.by_position && self.by_id == other.by_id - } -} -impl<A: Eq> Eq for EntityMap<A> {} - -const BY_POS_INVARIANT: &str = - "Invariant: All references in EntityMap.by_position should point to existent references in by_id"; - -impl<A> EntityMap<A> { - pub fn new() -> EntityMap<A> { - EntityMap { - by_position: BTreeMap::new(), - by_id: HashMap::new(), - last_id: 0, - } - } - - pub fn len(&self) -> usize { - self.by_id.len() - } - - /// Returns a list of all entities at the given position - pub fn at<'a>(&'a self, pos: Position) -> Vec<&'a A> { - self.by_position - .get(&pos) - .iter() - .flat_map(|eids| { - eids.iter() - .map(|eid| self.by_id.get(eid).expect(BY_POS_INVARIANT)) - }) - .collect() - } - - /// Remove all entities at the given position - pub fn remove_all_at(&mut self, pos: Position) { - if let Some(eids) = self.by_position.remove(&pos) { - for eid in eids { - self.by_id.remove(&eid).expect(BY_POS_INVARIANT); - } - } - } - - pub fn get(&self, id: EntityID) -> Option<&A> { - self.by_id.get(&id) - } - - pub fn get_mut(&mut self, id: EntityID) -> Option<&mut A> { - self.by_id.get_mut(&id) - } - - pub fn entities(&self) -> impl Iterator<Item = &A> { - self.by_id.values() - } - - pub fn entities_mut(&mut self) -> impl Iterator<Item = &mut A> { - self.by_id.values_mut() - } - - pub fn ids(&self) -> hash_map::Keys<'_, EntityID, A> { - self.by_id.keys() - } - - pub fn drain(&mut self) -> Drain<'_, A> { - let ids = self.ids().copied().collect::<Vec<_>>(); - Drain { - map: self, - ids_iter: Box::new(ids.into_iter()), - } - } - - fn next_id(&mut self) -> EntityID { - self.last_id += 1; - self.last_id - } -} - -impl<A: Positioned + Identified<EntityID>> EntityMap<A> { - pub fn insert(&mut self, mut entity: A) -> EntityID { - let pos = entity.position(); - let entity_id = self.next_id(); - entity.set_id(entity_id); - self.by_id.entry(entity_id).or_insert(entity); - self.by_position - .entry(pos) - .or_insert_with(Vec::new) - .push(entity_id); - entity_id - } - - /// Remove the entity with the given ID - pub fn remove(&mut self, id: EntityID) -> Option<A> { - self.by_id.remove(&id).map(|e| { - let mut empty = false; - let position = e.position(); - - if let Some(es) = self.by_position.get_mut(&position) { - es.retain(|e| *e != id); - if es.is_empty() { - empty = true; - } - } - - if empty { - self.by_position.remove(&position); - } - e - }) - } - - /// Moves all elements from `other` into `Self`, leathing `other` empty. - pub fn append(&mut self, other: &mut Self) { - // TODO there's probably some perf opportunities here by calling - // reserve() on stuff - for (_, entity) in other.drain() { - self.insert(entity); - } - } - - /// Gets all 8 neighbors of the given position. - pub fn neighbors<'a>( - &'a self, - position: Position, - ) -> Neighbors<Vec<(EntityID, &'a A)>> { - Neighbors::of_position(position) - .map(|pos| self.at(*pos)) - .mapmap(&|e| (e.id(), *e)) - } - - pub fn neighbor_entities<'a>( - &'a self, - position: Position, - ) -> Neighbors<Vec<&'a A>> { - self.neighbors(position).mapmap(&|(_eid, ent)| *ent) - } - - pub fn check_invariants(&self) { - for (id, ent) in &self.by_id { - assert_eq!(*id, ent.id()); - } - - for (pos, ents) in &self.by_position { - for eid in ents { - let ent = self.by_id.get(eid).unwrap(); - assert_eq!(*pos, ent.position()) - } - } - } -} - -impl<'a, A: Positioned + Identified<EntityID>> IntoIterator - for &'a EntityMap<A> -{ - type Item = (&'a EntityID, &'a A); - type IntoIter = std::collections::hash_map::Iter<'a, EntityID, A>; - fn into_iter(self) -> Self::IntoIter { - (&self.by_id).iter() - } -} - -impl<A: Positioned + Identified<EntityID>> IntoIterator for EntityMap<A> { - type Item = (EntityID, A); - type IntoIter = std::collections::hash_map::IntoIter<EntityID, A>; - fn into_iter(self) -> Self::IntoIter { - self.by_id.into_iter() - } -} - -impl<A: Positioned + Identified<EntityID>> FromIterator<A> for EntityMap<A> { - fn from_iter<I: IntoIterator<Item = A>>(iter: I) -> Self { - let mut em = EntityMap::new(); - for ent in iter { - em.insert(ent); - } - em - } -} - -impl<A: Positioned + Identified<EntityID> + Eq + Clone> AbstractMagma<Additive> - for EntityMap<A> -{ - fn operate(&self, right: &Self) -> Self { - let mut by_position = self.by_position.clone(); - by_position.append(&mut right.by_position.clone()); - - let mut by_id = self.by_id.clone(); - for (k, v) in right.by_id.clone() { - by_id.insert(k, v); - } - - EntityMap { - by_position, - by_id, - last_id: self.last_id.max(right.last_id), - } - } -} - -impl<A: Positioned + Identified<EntityID> + Eq + Clone> - AbstractSemigroup<Additive> for EntityMap<A> -{ -} - -impl<A: Positioned + Identified<EntityID> + Eq> Identity<Additive> - for EntityMap<A> -{ - fn identity() -> Self { - EntityMap::new() - } -} - -impl<A: Positioned + Identified<EntityID> + Eq + Clone> AbstractMonoid<Additive> - for EntityMap<A> -{ -} - -impl<A: PositionedMut> EntityMap<A> { - pub fn update_position( - &mut self, - entity_id: EntityID, - new_position: Position, - ) { - let mut old_pos = None; - if let Some(entity) = self.by_id.get_mut(&entity_id) { - if entity.position() == new_position { - return; - } - old_pos = Some(entity.position()); - entity.set_position(new_position); - } - - if let Some(p) = old_pos { - if let Some(es) = self.by_position.get_mut(&p) { - es.retain(|e| *e != entity_id); - } - - self.by_position - .entry(new_position) - .or_insert_with(Vec::new) - .push(entity_id); - } - } -} - -pub struct Drain<'a, A> { - map: &'a mut EntityMap<A>, - ids_iter: Box<dyn Iterator<Item = EntityID> + 'a>, -} - -impl<A: Positioned + Identified<EntityID>> Iterator for Drain<'_, A> { - type Item = (EntityID, A); - - fn next(&mut self) -> Option<Self::Item> { - self.ids_iter - .next() - .map(|eid| (eid, self.map.remove(eid).expect(BY_POS_INVARIANT))) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::types::PositionedMut; - use proptest::prelude::*; - use proptest_derive::Arbitrary; - - #[derive(Debug, Arbitrary, PartialEq, Eq, Clone)] - struct TestEntity { - _id: Option<EntityID>, - position: Position, - name: String, - } - - impl Positioned for TestEntity { - fn position(&self) -> Position { - self.position - } - } - - impl PositionedMut for TestEntity { - fn set_position(&mut self, pos: Position) { - self.position = pos - } - } - - impl Identified<EntityID> for TestEntity { - fn opt_id(&self) -> Option<EntityID> { - self._id - } - - fn set_id(&mut self, id: EntityID) { - self._id = Some(id); - } - } - - fn gen_entity_map() -> BoxedStrategy<EntityMap<TestEntity>> { - any::<Vec<TestEntity>>() - .prop_map(|ents| { - ents.iter().cloned().collect::<EntityMap<TestEntity>>() - }) - .boxed() - } - - proptest! { - #![proptest_config(ProptestConfig::with_cases(10))] - - #[test] - fn test_entity_map_len(items: Vec<TestEntity>) { - let mut map = EntityMap::new(); - assert_eq!(map.len(), 0); - for ent in &items { - map.insert(ent.clone()); - } - assert_eq!(map.len(), items.len()); - } - - #[test] - fn test_entity_map_getset( - mut em in gen_entity_map(), - ent: TestEntity - ) { - em.insert(ent.clone()); - assert!(em.at(ent.position).iter().any(|e| e.name == ent.name)) - } - - #[test] - fn test_entity_map_set_iter_contains( - mut em in gen_entity_map(), - ent: TestEntity - ) { - em.insert(ent.clone()); - assert!(em.entities().any(|e| e.name == ent.name)) - } - - #[test] - fn test_update_position( - mut em in gen_entity_map(), - ent: TestEntity, - new_position: Position, - ) { - let original_position = ent.position(); - let entity_id = em.insert(ent.clone()); - em.update_position(entity_id, new_position); - - if new_position != original_position { - assert!(em.at(original_position).iter().all(|e| e.name != ent.name)); - } - assert_eq!( - em.get(entity_id).map(|e| e.position()), - Some(new_position) - ); - assert!( - em.at(new_position).iter().map( - |e| e.name.clone()).any(|en| en == ent.name), - ) - } - - #[test] - fn test_remove_all_at( - mut em in gen_entity_map(), - pos: Position, - ) { - em.remove_all_at(pos); - assert_eq!(em.at(pos).len(), 0); - } - - #[test] - fn test_entity_map_semigroup_laws( - em1 in gen_entity_map(), - em2 in gen_entity_map(), - em3 in gen_entity_map(), - ) { - assert!(AbstractSemigroup::prop_is_associative((em1, em2, em3))); - } - - fn test_entity_map_monoid_laws( - em in gen_entity_map(), - ) { - assert!( - AbstractMonoid::prop_operating_identity_element_is_noop((em,)) - ); - } - - #[test] - fn test_entity_map_append( - mut target in gen_entity_map(), - mut source in gen_entity_map(), - ) { - let orig_target = target.clone(); - let orig_source = source.clone(); - - target.append(&mut source); - target.check_invariants(); - - assert_eq!(source, EntityMap::new()); - - for ent in orig_source.entities() { - assert!( - target.at(ent.position()).iter().any(|e| e.name == ent.name) - ); - } - - for ent in orig_target.entities() { - assert!( - target.at(ent.position()).iter().any(|e| e.name == ent.name) - ); - } - } - } -} diff --git a/src/types/menu.rs b/src/types/menu.rs deleted file mode 100644 index 63abc837788e..000000000000 --- a/src/types/menu.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::types::Dimensions; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct MenuInfo { - pub prompt: String, - pub options: Vec<String>, -} - -impl MenuInfo { - pub fn new(prompt: String, options: Vec<String>) -> Self { - MenuInfo { prompt, options } - } - - /// Returns the inner dimensions of a box necessary to draw this menu. Will - /// not trim either dimension to the size of the terminal - pub fn dimensions(&self) -> Dimensions { - Dimensions { - w: self - .options - .iter() - .map(|s| s.len()) - .max() - .unwrap_or(0) - .max(self.prompt.len()) as u16 - + 4, - h: self.options.len() as u16 - + if self.prompt.is_empty() { 0 } else { 2 } - + 4, - } - } -} diff --git a/src/types/mod.rs b/src/types/mod.rs deleted file mode 100644 index d417e873d8ca..000000000000 --- a/src/types/mod.rs +++ /dev/null @@ -1,504 +0,0 @@ -#![allow(clippy::unit_arg)] -#![allow(clippy::identity_conversion)] - -use std::cmp::max; -use std::cmp::Ordering; -use std::ops; -use std::rc::Rc; - -pub mod collision; -pub mod command; -pub mod direction; -pub mod entity_map; -pub mod menu; - -pub use collision::Collision; -pub use direction::Direction; -pub use direction::Direction::*; -use proptest_derive::Arbitrary; -use termion::cursor; - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -pub struct Dimensions { - #[proptest(strategy = "std::ops::Range::<u16>::from(0..100)")] - pub w: u16, - - #[proptest(strategy = "std::ops::Range::<u16>::from(0..100)")] - pub h: u16, -} - -pub const ZERO_DIMENSIONS: Dimensions = Dimensions { w: 0, h: 0 }; -pub const UNIT_DIMENSIONS: Dimensions = Dimensions { w: 1, h: 1 }; - -impl Default for Dimensions { - fn default() -> Self { - Dimensions { w: 80, h: 20 } - } -} - -impl ops::Sub<Dimensions> for Dimensions { - type Output = Dimensions; - fn sub(self, dims: Dimensions) -> Dimensions { - Dimensions { - w: self.w - dims.w, - h: self.h - dims.h, - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -pub struct BoundingBox { - pub dimensions: Dimensions, - pub position: Position, -} - -impl BoundingBox { - pub fn at_origin(dimensions: Dimensions) -> BoundingBox { - BoundingBox { - dimensions, - position: ORIGIN, - } - } - - pub fn from_corners( - top_left: Position, - lower_right: Position, - ) -> BoundingBox { - BoundingBox { - position: top_left, - dimensions: Dimensions { - w: (lower_right.x - top_left.x) as u16, - h: (lower_right.y - top_left.y) as u16, - }, - } - } - - pub fn lr_corner(self) -> Position { - self.position - + (Position { - x: self.dimensions.w as i16, - y: self.dimensions.h as i16, - }) - } - - pub fn ll_corner(self) -> Position { - self.position - + (Position { - x: 0, - y: self.dimensions.h as i16, - }) - } - - /// Returns a bounding box representing the *inside* of this box if it was - /// drawn on the screen. - pub fn inner(self) -> BoundingBox { - self + UNIT_POSITION - UNIT_DIMENSIONS - UNIT_DIMENSIONS - } - - /// Moves the top right corner of the bounding box by the offset specified - /// by the given position, keeping the lower right corner in place - pub fn move_tr_corner(self, offset: Position) -> BoundingBox { - self + offset - - Dimensions { - w: offset.x as u16, - h: offset.y as u16, - } - } -} - -impl ops::Add<Position> for BoundingBox { - type Output = BoundingBox; - fn add(self, pos: Position) -> BoundingBox { - BoundingBox { - position: self.position + pos, - ..self - } - } -} - -impl ops::Sub<Dimensions> for BoundingBox { - type Output = BoundingBox; - fn sub(self, dims: Dimensions) -> BoundingBox { - BoundingBox { - dimensions: self.dimensions - dims, - ..self - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary, Hash, Ord)] -pub struct Position { - /// x (horizontal) position - #[proptest(strategy = "std::ops::Range::<i16>::from(0..100)")] - pub x: i16, - - #[proptest(strategy = "std::ops::Range::<i16>::from(0..100)")] - /// y (vertical) position - pub y: i16, -} - -pub fn pos(x: i16, y: i16) -> Position { - Position { x, y } -} - -pub const ORIGIN: Position = Position { x: 0, y: 0 }; -pub const UNIT_POSITION: Position = Position { x: 1, y: 1 }; - -impl Position { - /// Returns true if this position exists within the bounds of the given box, - /// inclusive - pub fn within(self, b: BoundingBox) -> bool { - (self > b.position - UNIT_POSITION) && self < (b.lr_corner()) - } - - /// Returns a sequence of ASCII escape characters for moving the cursor to - /// this Position - pub fn cursor_goto(self) -> cursor::Goto { - // + 1 because Goto is 1-based, but position is 0-based - cursor::Goto(self.x as u16 + 1, self.y as u16 + 1) - } - - /// Converts this position to the number of `Tiles` away from the origin it - /// represents. Usually done after subtracting two positions. Gives distance - /// as the crow flies - pub fn as_tiles(self) -> Tiles { - Tiles(max(self.x.abs(), self.y.abs()).into()) - } -} - -impl PartialOrd for Position { - fn partial_cmp(&self, other: &Position) -> Option<Ordering> { - if self.x == other.x && self.y == other.y { - Some(Ordering::Equal) - } else if self.x > other.x && self.y > other.y { - Some(Ordering::Greater) - } else if self.x < other.x && self.y < other.y { - Some(Ordering::Less) - } else { - None - } - } -} - -/// Implements (bounded) addition of a Dimension to a position. -/// -/// # Examples -/// -/// ``` -/// let pos = Position { x: 1, y: 10 } -/// -/// let left_pos = pos + Direction::Left -/// assert_eq!(left, Position { x: 0, y: 10 }) -/// -/// let right_pos = pos + Direction::Right -/// assert_eq!(right_pos, Position { x: 0, y: 10 }) -/// ``` -#[allow(clippy::suspicious_arithmetic_impl)] -impl ops::Add<Direction> for Position { - type Output = Position; - fn add(self, dir: Direction) -> Position { - match dir { - Left => { - if self.x > std::i16::MIN { - Position { - x: self.x - 1, - ..self - } - } else { - self - } - } - Right => { - if self.x < std::i16::MAX { - Position { - x: self.x + 1, - ..self - } - } else { - self - } - } - Up => { - if self.y > std::i16::MIN { - Position { - y: self.y - 1, - ..self - } - } else { - self - } - } - Down => { - if self.y < std::i16::MAX { - Position { - y: self.y + 1, - ..self - } - } else { - self - } - } - UpLeft => self + Up + Left, - UpRight => self + Up + Right, - DownLeft => self + Down + Left, - DownRight => self + Down + Right, - } - } -} - -impl ops::Add<Position> for Position { - type Output = Position; - fn add(self, pos: Position) -> Position { - Position { - x: self.x + pos.x, - y: self.y + pos.y, - } - } -} - -impl ops::Sub<Position> for Position { - type Output = Position; - fn sub(self, pos: Position) -> Position { - Position { - x: self.x - pos.x, - y: self.y - pos.y, - } - } -} - -impl Positioned for Position { - fn position(&self) -> Position { - *self - } -} - -pub trait Positioned { - fn x(&self) -> i16 { - self.position().x - } - - fn y(&self) -> i16 { - self.position().y - } - - fn position(&self) -> Position { - Position { - x: self.x(), - y: self.y(), - } - } -} - -pub trait PositionedMut: Positioned { - fn set_position(&mut self, pos: Position); -} - -// impl<A, I> Positioned for A where A : Deref<Target = I>, I: Positioned { -// fn position(&self) -> Position { -// self.position() -// } -// } - -impl<T: Positioned> Positioned for Box<T> { - fn position(&self) -> Position { - (**self).position() - } -} - -impl<'a, T: Positioned> Positioned for &'a T { - fn position(&self) -> Position { - (**self).position() - } -} - -impl<'a, T: Positioned> Positioned for &'a mut T { - fn position(&self) -> Position { - (**self).position() - } -} - -impl<'a, T: Positioned> Positioned for Rc<T> { - fn position(&self) -> Position { - (**self).position() - } -} - -impl<'a, T: PositionedMut> PositionedMut for &'a mut T { - fn set_position(&mut self, pos: Position) { - (**self).set_position(pos) - } -} - -#[macro_export] -macro_rules! positioned { - ($name:ident) => { - positioned!($name, position); - }; - ($name:ident, $attr:ident) => { - impl $crate::types::Positioned for $name { - fn position(&self) -> $crate::types::Position { - self.$attr - } - } - }; -} - -#[macro_export] -macro_rules! positioned_mut { - ($name:ident) => { - positioned_mut!($name, position); - }; - ($name:ident, $attr:ident) => { - impl crate::types::PositionedMut for $name { - fn set_position(&mut self, pos: $crate::types::Position) { - self.$attr = pos; - } - } - }; -} - -/// A number of ticks -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -pub struct Ticks(pub u16); - -/// A number of tiles -/// -/// Expressed in terms of a float to allow moving partial tiles in a number of -/// ticks -#[derive(Clone, Copy, Debug, PartialEq, Arbitrary)] -pub struct Tiles(pub f32); - -/// The speed of an entity, expressed in ticks per tile -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary, Deserialize)] -#[serde(transparent)] -pub struct Speed(pub u32); - -impl Speed { - /// Returns the number of tiles that would be moved in the given number of - /// ticks at this speed - pub fn ticks_to_tiles(self, ticks: Ticks) -> Tiles { - Tiles(f32::from(ticks.0) / self.0 as f32) - } - - /// Returns the number of ticks required to move the given number of tiles - /// at this speed - pub fn tiles_to_ticks(self, tiles: Tiles) -> Ticks { - Ticks(tiles.0 as u16 * self.0 as u16) - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary)] -pub struct Neighbors<A> { - pub top_left: A, - pub top: A, - pub top_right: A, - pub left: A, - pub right: A, - pub bottom_left: A, - pub bottom: A, - pub bottom_right: A, -} - -impl Neighbors<Position> { - fn of_position(pos: Position) -> Self { - Neighbors { - top_left: pos + Direction::UpLeft, - top: pos + Direction::Up, - top_right: pos + Direction::UpRight, - left: pos + Direction::Left, - right: pos + Direction::Right, - bottom_left: pos + Direction::DownLeft, - bottom: pos + Direction::Down, - bottom_right: pos + Direction::DownRight, - } - } -} - -impl<A> Neighbors<A> { - /// it's a functor, yo - pub fn map<B, F: Fn(&A) -> B>(&self, f: F) -> Neighbors<B> { - Neighbors { - top_left: f(&self.top_left), - top: f(&self.top), - top_right: f(&self.top_right), - left: f(&self.left), - right: f(&self.right), - bottom_left: f(&self.bottom_left), - bottom: f(&self.bottom), - bottom_right: f(&self.bottom_right), - } - } -} - -impl<A> Neighbors<Vec<A>> { - pub fn mapmap<B, F: Fn(&A) -> B>(&self, f: &F) -> Neighbors<Vec<B>> { - self.map(|xs| xs.iter().map(f).collect()) - } -} - -#[cfg(test)] -mod tests { - #![allow(clippy::unnecessary_operation)] - use super::*; - use proptest::prelude::*; - - proptest! { - #[test] - fn position_partialord_lt_transitive( - a: Position, - b: Position, - c: Position - ) { - if a < b && b < c { - assert!(a < c) - } - } - - #[test] - fn position_partialord_eq_transitive( - a: Position, - b: Position, - c: Position - ) { - if a == b && b == c { - assert!(a == c) - } - } - - #[test] - fn position_partialord_gt_transitive( - a: Position, - b: Position, - c: Position, - ) { - if a > b && b > c { - assert!(a > c) - } - } - - #[test] - fn position_partialord_antisymmetric(a: Position, b: Position) { - if a < b { - assert!(!(a > b)) - } else if a > b { - assert!(!(a < b)) - } - } - - #[test] - fn test_position_plus_dimension_as_tiles_monoid_action( - pos: Position, - dir: Direction, - ) { - prop_assume!(pos.y > 0 && pos.x > 0); - assert_eq!(((pos + dir) - pos).as_tiles(), Tiles(1.0)); - } - } - - #[test] - fn test_position_as_tiles() { - assert_eq!(pos(0, 0).as_tiles(), Tiles(0.0)); - assert_eq!(pos(1, 1).as_tiles(), Tiles(1.0)); - assert_eq!(pos(1, 2).as_tiles(), Tiles(2.0)); - } -} diff --git a/src/util/mod.rs b/src/util/mod.rs deleted file mode 100644 index dd5087a55558..000000000000 --- a/src/util/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -#[macro_use] -pub mod static_cfg; -#[macro_use] -pub mod template; -pub mod promise; -#[macro_use] -pub mod trait_impls; diff --git a/src/util/promise.rs b/src/util/promise.rs deleted file mode 100644 index 22f1e8b47f58..000000000000 --- a/src/util/promise.rs +++ /dev/null @@ -1,160 +0,0 @@ -use std::future::Future; -use std::pin::Pin; -use std::sync::{Arc, RwLock}; -use std::task::{Context, Poll, Waker}; - -type Waiter<Env, T> = Box<dyn Fn(&mut Env, &T)>; - -pub struct Promise<Env, T> { - inner: Arc<RwLock<Inner<T>>>, - waiters: Arc<RwLock<Vec<Waiter<Env, T>>>>, -} - -pub struct Complete<T> { - inner: Arc<RwLock<Inner<T>>>, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Cancelled; - -struct Inner<T> { - value: Option<Arc<T>>, - waker: Option<Waker>, -} - -pub fn promise<Env, T>() -> (Complete<T>, Promise<Env, T>) { - let inner = Arc::new(RwLock::new(Inner { - value: None, - waker: None, - })); - let promise = Promise { - inner: inner.clone(), - waiters: Arc::new(RwLock::new(Vec::new())), - }; - let complete = Complete { inner }; - (complete, promise) -} - -impl<T> Complete<T> { - pub fn fulfill(&self, val: T) { - let mut inner = self.inner.write().unwrap(); - inner.value = Some(Arc::new(val)); - if let Some(waker) = inner.waker.take() { - waker.wake() - } - } -} - -impl<T> Complete<Result<T, Cancelled>> { - pub fn cancel(&mut self) { - self.fulfill(Err(Cancelled)) - } -} - -impl<E, T> Complete<Result<T, E>> { - pub fn ok(&mut self, val: T) { - self.fulfill(Ok(val)) - } - - pub fn err(&mut self, e: E) { - self.fulfill(Err(e)) - } -} - -impl<Env, T> Promise<Env, T> { - pub fn on_fulfill<F: Fn(&mut Env, &T) + 'static>(&mut self, f: F) { - let mut waiters = self.waiters.write().unwrap(); - waiters.push(Box::new(f)); - } -} - -impl<Env, T> Promise<Env, Result<T, Cancelled>> { - pub fn on_cancel<F: Fn(&mut Env) + 'static>(&mut self, f: F) { - self.on_err(move |env, _| f(env)) - } -} - -impl<Env, E, T> Promise<Env, Result<T, E>> { - pub fn on_ok<F: Fn(&mut Env, &T) + 'static>(&mut self, f: F) { - self.on_fulfill(move |env, r| { - if let Ok(val) = r { - f(env, val) - } - }) - } - - pub fn on_err<F: Fn(&mut Env, &E) + 'static>(&mut self, f: F) { - self.on_fulfill(move |env, r| { - if let Err(e) = r { - f(env, e) - } - }) - } -} - -pub trait Give<Env> { - fn give(&self, env: &mut Env) -> bool; -} - -impl<Env, T> Give<Env> for Promise<Env, T> { - fn give(&self, env: &mut Env) -> bool { - let inner = self.inner.read().unwrap(); - if let Some(value) = &inner.value { - let mut waiters = self.waiters.write().unwrap(); - for waiter in waiters.iter() { - waiter(env, value); - } - waiters.clear(); - true - } else { - false - } - } -} - -impl<Env, T> Clone for Promise<Env, T> { - fn clone(&self) -> Self { - Promise { - inner: self.inner.clone(), - waiters: self.waiters.clone(), - } - } -} - -impl<Env, P: Give<Env>> Give<Env> for &P { - fn give(&self, env: &mut Env) -> bool { - (*self).give(env) - } -} - -impl<Env, T> Future for Promise<Env, T> { - type Output = Arc<T>; - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let mut inner = self.inner.write().unwrap(); - match inner.value { - Some(ref v) => Poll::Ready(v.clone()), - None => { - inner.waker = Some(cx.waker().clone()); - Poll::Pending - } - } - } -} - -pub struct Promises<'a, Env> { - ps: Vec<Box<dyn Give<Env> + 'a>>, -} - -impl<'a, Env> Promises<'a, Env> { - pub fn new() -> Self { - Promises { ps: Vec::new() } - } - - pub fn push(&mut self, p: Box<dyn Give<Env> + 'a>) { - self.ps.push(p); - } - - pub fn give_all(&mut self, env: &mut Env) { - self.ps.retain(|p| !p.give(env)); - } -} diff --git a/src/util/static_cfg.rs b/src/util/static_cfg.rs deleted file mode 100644 index b20456fb3bd4..000000000000 --- a/src/util/static_cfg.rs +++ /dev/null @@ -1,147 +0,0 @@ -use include_dir::Dir; -use serde::de; - -macro_rules! __static_cfg_include { - (toml_file, $filename:expr) => { - include_str!($filename) - }; - (toml_dir, $filename:expr) => { - include_dir!($filename) - }; - (json_file, $filename:expr) => { - include_str!($filename) - }; - (json_dir, $filename:expr) => { - include_dir!($filename) - }; - (cfg_dir, $filename:expr) => { - include_dir!($filename) - }; -} - -macro_rules! __static_cfg_type { - (toml_file) => (&'static str); - (json_file) => (&'static str); - (toml_dir) => (include_dir::Dir<'static>); - (json_dir) => (include_dir::Dir<'static>); - (cfg_dir) => (include_dir::Dir<'static>); -} - -macro_rules! __static_cfg_parse { - (toml_file, $e:expr) => { - toml::from_str($e).unwrap() - }; - - (json_file, $e:expr) => { - serde_json::from_str($e).unwrap() - }; - - (toml_dir, $e:expr) => { - crate::util::static_cfg::parse_toml_dir($e) - }; - - (json_dir, $e:expr) => { - crate::util::static_cfg::parse_json_dir($e) - }; - - (cfg_dir, $e:expr) => { - crate::util::static_cfg::parse_cfg_dir($e); - }; -} - -macro_rules! __static_cfg_inner { - ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $kind:ident($filename:expr); $($t:tt)*) => { - // static RAW: &'static str = __static_cfg_include!($kind, $filename); - static RAW: __static_cfg_type!($kind) = __static_cfg_include!($kind, $filename); - lazy_static! { - $(#[$attr])* static ref $N: $T = __static_cfg_parse!($kind, RAW); - } - - static_cfg!($($t)*); - } -} - -#[macro_export] -macro_rules! static_cfg { - ($(#[$attr:meta])* static ref $N:ident : $T:ty = $kind:ident($filename:expr); $($t:tt)*) => { - __static_cfg_inner!($(#[$attr])* () static ref $N : $T = $kind($filename); $($t)*); - }; - - ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $kind:ident($filename:expr); $($t:tt)*) => { - __static_cfg_inner!($(#[$attr])* (pub) static ref $N : $T = $kind($filename); $($t)*); - }; - - ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $kind:ident($filename:expr); $($t:tt)*) => { - __static_cfg_inner!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $kind($filename); $($t)*); - }; - - () => () -} - -pub fn parse_cfg_dir<'a, T>(d: Dir<'a>) -> Vec<T> -where - T: de::Deserialize<'a>, -{ - d.files() - .iter() - .filter_map(|f| { - let path = f.path(); - let contents = f.contents_utf8().unwrap(); - match path.extension().and_then(|e| e.to_str()) { - Some("toml") => { - Some(toml::from_str(contents).unwrap_or_else(|e| { - panic!( - "Error parsing TOML file {}: {}", - path.display(), - e - ) - })) - } - Some("json") => { - Some(serde_json::from_str(contents).unwrap_or_else(|e| { - panic!( - "Error parsing JSON file {}: {}", - path.display(), - e - ) - })) - } - // > YAML currently does not support zero-copy deserialization - // Some("yaml") => { - // Some(serde_yaml::from_str(contents).unwrap_or_else(|e| { - // panic!( - // "Error parsing YAML file {}: {}", - // path.display(), - // e - // ) - // })) - // } - _ => None, - } - }) - .collect() -} - -pub fn parse_toml_dir<'a, T>(d: Dir<'a>) -> Vec<T> -where - T: de::Deserialize<'a>, -{ - d.files() - .iter() - .map(|f| { - toml::from_str(f.contents_utf8().unwrap()).unwrap_or_else(|e| { - panic!("Error parsing TOML file {}: {}", f.path, e) - }) - }) - .collect() -} - -pub fn parse_json_dir<'a, T>(d: Dir<'a>) -> Vec<T> -where - T: de::Deserialize<'a>, -{ - d.files() - .iter() - .map(|f| serde_json::from_str(f.contents_utf8().unwrap()).unwrap()) - .collect() -} diff --git a/src/util/template.rs b/src/util/template.rs deleted file mode 100644 index bb77f9b4d610..000000000000 --- a/src/util/template.rs +++ /dev/null @@ -1,362 +0,0 @@ -use nom::combinator::rest; -use nom::error::ErrorKind; -use nom::{Err, IResult}; -use std::collections::HashMap; -use std::fmt::{self, Display}; -use std::marker::PhantomData; - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Path<'a> { - head: &'a str, - tail: Vec<&'a str>, -} - -impl<'a> Path<'a> { - fn new(head: &'a str, tail: Vec<&'a str>) -> Self { - Path { head, tail } - } -} - -impl<'a> Display for Path<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.head)?; - for part in &self.tail { - write!(f, ".{}", part)?; - } - Ok(()) - } -} - -// named!(path_ident, map_res!(is_not!(".}"), std::str::from_utf8)); -fn path_ident<'a>(input: &'a str) -> IResult<&'a str, &'a str> { - take_till!(input, |c| c == '.' || c == '}') -} - -fn path<'a>(input: &'a str) -> IResult<&'a str, Path<'a>> { - map!( - input, - tuple!( - path_ident, - many0!(complete!(preceded!(char!('.'), path_ident))) - ), - |(h, t)| Path::new(h, t) - ) -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub enum TemplateToken<'a> { - Literal(&'a str), - Substitution(Path<'a>), -} - -fn token_substitution<'a>( - input: &'a str, -) -> IResult<&'a str, TemplateToken<'a>> { - map!( - input, - delimited!(tag!("{{"), path, tag!("}}")), - TemplateToken::Substitution - ) -} - -fn template_token<'a>(input: &'a str) -> IResult<&'a str, TemplateToken<'a>> { - alt!( - input, - token_substitution - | map!( - alt!(complete!(take_until!("{{")) | complete!(rest)), - TemplateToken::Literal - ) - ) -} - -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct Template<'a> { - tokens: Vec<TemplateToken<'a>>, -} - -impl<'a> Template<'a> { - pub fn new(tokens: Vec<TemplateToken<'a>>) -> Self { - Template { tokens } - } -} - -pub struct TemplateVisitor<'a> { - marker: PhantomData<fn() -> Template<'a>>, -} - -impl<'a> TemplateVisitor<'a> { - pub fn new() -> Self { - TemplateVisitor { - marker: PhantomData, - } - } -} - -impl<'a> serde::de::Visitor<'a> for TemplateVisitor<'a> { - type Value = Template<'a>; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - formatter.write_str("a valid template string") - } - - fn visit_borrowed_str<E: serde::de::Error>( - self, - v: &'a str, - ) -> Result<Self::Value, E> { - Template::parse(v).map_err(|_| { - serde::de::Error::invalid_value( - serde::de::Unexpected::Str(v), - &"a valid template string", - ) - }) - } -} - -impl<'a> serde::Deserialize<'a> for Template<'a> { - fn deserialize<D: serde::Deserializer<'a>>( - deserializer: D, - ) -> Result<Self, D::Error> { - deserializer.deserialize_str(TemplateVisitor::new()) - } -} - -impl<'a> Template<'a> { - pub fn parse( - input: &'a str, - ) -> Result<Template<'a>, Err<(&'a str, ErrorKind)>> { - let (remaining, res) = template(input)?; - if !remaining.is_empty() { - unreachable!(); - } - Ok(res) - } - - pub fn format( - &self, - params: &TemplateParams<'a>, - ) -> Result<String, TemplateError<'a>> { - use TemplateToken::*; - let mut res = String::new(); - for token in &self.tokens { - match token { - Literal(s) => res.push_str(s), - Substitution(p) => match params.get(p.clone()) { - Some(s) => res.push_str(s), - None => return Err(TemplateError::MissingParam(p.clone())), - }, - } - } - Ok(res) - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum TemplateError<'a> { - MissingParam(Path<'a>), -} - -impl<'a> Display for TemplateError<'a> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use TemplateError::*; - match self { - MissingParam(path) => { - write!(f, "Missing template parameter: {}", path) - } - } - } -} - -#[derive(Debug, PartialEq, Eq)] -pub enum TemplateParams<'a> { - Direct(&'a str), - Nested(HashMap<&'a str, TemplateParams<'a>>), -} - -impl<'a> TemplateParams<'a> { - fn get(&self, path: Path<'a>) -> Option<&'a str> { - use TemplateParams::*; - match self { - Direct(_) => None, - Nested(m) => m.get(path.head).and_then(|next| { - if path.tail.is_empty() { - match next { - Direct(s) => Some(*s), - _ => None, - } - } else { - next.get(Path { - head: path.tail[0], - tail: path.tail[1..].to_vec(), - }) - } - }), - } - } -} - -#[macro_export] -macro_rules! template_params { - (@count $head: expr => $hv: tt, $($rest:tt)+) => { 1 + template_params!(@count $($rest)+) }; - (@count $one:expr => $($ov: tt)*) => { 1 }; - (@inner $ret: ident, ($key: expr => {$($v:tt)*}, $($r:tt)*)) => { - $ret.insert($key, template_params!({ $($v)* })); - template_params!(@inner $ret, ($($r)*)); - }; - (@inner $ret: ident, ($key: expr => $value: expr, $($r:tt)*)) => { - $ret.insert($key, template_params!($value)); - template_params!(@inner $ret, ($($r)*)); - }; - (@inner $ret: ident, ()) => {}; - - ({ $($body: tt)* }) => {{ - let _cap = template_params!(@count $($body)*); - let mut _m = ::std::collections::HashMap::with_capacity(_cap); - template_params!(@inner _m, ($($body)*)); - TemplateParams::Nested(_m) - }}; - - ($direct:expr) => { TemplateParams::Direct($direct) }; - - () => { TemplateParams::Nested(::std::collections::HashMap::new()) }; -} - -fn template<'a>(input: &'a str) -> IResult<&'a str, Template<'a>> { - complete!( - input, - map!(many1!(complete!(template_token)), Template::new) - ) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_parse_path_ident() { - assert_eq!(path_ident("foo}}"), Ok(("}}", "foo"))); - assert_eq!(path_ident("foo.bar}}"), Ok((".bar}}", "foo"))); - } - - #[test] - fn test_parse_path() { - assert_eq!(path("foo}}"), Ok(("}}", Path::new("foo", vec![])))); - assert_eq!( - path("foo.bar}}"), - Ok(("}}", Path::new("foo", vec!["bar"]))) - ); - assert_eq!( - path("foo.bar.baz}}"), - Ok(("}}", Path::new("foo", vec!["bar", "baz"]))) - ); - } - - #[test] - fn test_parse_template_token() { - assert_eq!( - template_token("foo bar"), - Ok(("", TemplateToken::Literal("foo bar"))) - ); - - assert_eq!( - template_token("foo bar {{baz}}"), - Ok(("{{baz}}", TemplateToken::Literal("foo bar "))) - ); - - assert_eq!( - template_token("{{baz}}"), - Ok(( - "", - TemplateToken::Substitution(Path::new("baz", Vec::new())) - )) - ); - - assert_eq!( - template_token("{{baz}} foo bar"), - Ok(( - " foo bar", - TemplateToken::Substitution(Path::new("baz", Vec::new())) - )) - ); - } - - #[test] - fn test_parse_template() { - assert_eq!( - template("foo bar"), - Ok(( - "", - Template { - tokens: vec![TemplateToken::Literal("foo bar")] - } - )) - ); - - assert_eq!( - template("foo bar {{baz}} qux"), - Ok(( - "", - Template { - tokens: vec![ - TemplateToken::Literal("foo bar "), - TemplateToken::Substitution(Path::new( - "baz", - Vec::new() - )), - TemplateToken::Literal(" qux"), - ] - } - )) - ); - } - - #[test] - fn test_template_params_literal() { - // trace_macros!(true); - let expected = template_params!({ - "direct" => "hi", - "other" => "here", - "nested" => { - "one" => "1", - "two" => "2", - "double" => { - "three" => "3", - }, - }, - }); - // trace_macros!(false); - assert_eq!( - TemplateParams::Nested(hashmap! { - "direct" => TemplateParams::Direct("hi"), - "other" => TemplateParams::Direct("here"), - "nested" => TemplateParams::Nested(hashmap!{ - "one" => TemplateParams::Direct("1"), - "two" => TemplateParams::Direct("2"), - "double" => TemplateParams::Nested(hashmap!{ - "three" => TemplateParams::Direct("3"), - }) - }) - }), - expected, - ) - } - - #[test] - fn test_format_template() { - assert_eq!( - "foo bar baz qux", - Template::parse("foo {{x}} {{y.z}} {{y.w.z}}") - .unwrap() - .format(&template_params!({ - "x" => "bar", - "y" => { - "z" => "baz", - "w" => { - "z" => "qux", - }, - }, - })) - .unwrap() - ) - } -} diff --git a/src/util/trait_impls.rs b/src/util/trait_impls.rs deleted file mode 100644 index ba15f7119d26..000000000000 --- a/src/util/trait_impls.rs +++ /dev/null @@ -1,17 +0,0 @@ -macro_rules! ref_impl { - (impl<T: $traitb: ident $(+ $bound:ident)*> $traiti:ident for &T { - $($body:tt)* - }) => { - impl<'a, T: $traitb $(+ $bound)*> $traiti for &'a T { - $($body)* - } - - impl<'a, T: $traitb $(+ $bound)*> $traiti for &'a mut T { - $($body)* - } - - impl<T: $traitb $(+ $bound)*> $traiti for ::std::boxed::Box<T> { - $($body)* - } - }; -} |