diff --git a/.travis.yml b/.travis.yml index 7266d3d..9b3bed2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,8 +4,6 @@ rust: - beta - nightly matrix: - allow_failures: - - rust: nightly fast_finish: true cache: cargo branches: diff --git a/Cargo.lock b/Cargo.lock index 0900ad6..d82ca72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,47 +1,51 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. [[package]] name = "aho-corasick" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arrayref" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "backtrace" -version = "0.3.9" +name = "autocfg" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] -name = "backtrace-sys" -version = "0.1.24" +name = "backtrace" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "base64" -version = "0.9.3" +name = "backtrace-sys" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -56,11 +60,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "block-buffer" -version = "0.2.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-buffer" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "block-padding" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -68,28 +91,33 @@ name = "byte-tools" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byteorder" -version = "1.2.6" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.25" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -115,50 +143,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crossbeam-deque" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "crossbeam-epoch" -version = "0.5.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossbeam-queue" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crossbeam-utils" -version = "0.5.0" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "digest" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "digest" -version = "0.6.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "erased-serde" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "eui48" -version = "0.3.2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -166,22 +214,22 @@ dependencies = [ [[package]] name = "failure" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.14 (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.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -189,6 +237,16 @@ name = "fake-simd" version = "0.1.2" source = "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 = "fuchsia-zircon" version = "0.3.3" @@ -205,7 +263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -213,21 +271,28 @@ name = "futures-cpupool" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "gcc" -version = "0.3.54" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "generic-array" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "generic-array" -version = "0.8.3" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -236,82 +301,111 @@ name = "glob" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "h2" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "handlebars" -version = "0.32.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "pest_derive 1.0.8 (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)", + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "hap" -version = "0.0.3" +version = "0.0.4" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "chacha20-poly1305-aead 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "erased-serde 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "eui48 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", + "erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "eui48 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)", "libmdns 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", "route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "srp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", + "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "srp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "http" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "httparse" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.27" +version = "0.12.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -321,22 +415,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "indexmap" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ipnetwork" -version = "0.12.8" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "itoa" @@ -352,32 +454,19 @@ dependencies = [ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "lazy_static" -version = "0.2.11" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "lazy_static" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "lazycell" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.43" +version = "0.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -385,16 +474,16 @@ name = "libmdns" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.10.0 (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.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -402,10 +491,10 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -414,17 +503,22 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.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" @@ -432,25 +526,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.0.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "memoffset" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "mime" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "mio" version = "0.6.16" @@ -460,12 +543,12 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -475,7 +558,7 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -495,7 +578,7 @@ name = "multimap" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -503,9 +586,9 @@ name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -514,49 +597,46 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nodrop" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num" -version = "0.1.42" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-bigint" -version = "0.1.44" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-complex" -version = "0.1.43" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -578,13 +658,12 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.1.42" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)", + "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -594,15 +673,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "opaque-debug" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -610,23 +694,23 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.6.4" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -636,103 +720,127 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pest" -version = "1.0.6" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "pest_derive" -version = "1.0.8" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pest_generator" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "pest_meta" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_datalink 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_packet 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_sys 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_transport 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_datalink 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_packet 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_transport 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_base" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pnet_datalink" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_sys 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_macros" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_macros_support" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_packet" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_macros 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_macros_support 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_macros 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_macros_support 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_sys" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pnet_transport" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_packet 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "pnet_sys 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_packet 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pnet_sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "proc-macro2" -version = "0.4.19" +version = "0.4.27" 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)", @@ -745,116 +853,185 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quote" -version = "0.3.15" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "quote" -version = "0.6.8" +name = "rand" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.3.22" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.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.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.4.3" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "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.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.5.5" +version = "0.6.5" 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-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (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.3 (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.6 (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.2 (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_core" -version = "0.2.1" +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 = "redox_syscall" -version = "0.1.40" +name = "rand_core" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "regex" -version = "0.2.11" +name = "rand_hc" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.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.1 (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 = "regex" -version = "1.0.5" +name = "rand_isaac" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.2 (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.1 (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 = "regex-syntax" -version = "0.5.6" +name = "rand_jitter" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "regex-syntax" -version = "0.6.2" +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.50 (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.6 (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 = [ - "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.2 (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 = "relay" +name = "rand_xorshift" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (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 = "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.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "regex" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "aho-corasick 0.6.10 (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.5 (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.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "regex-syntax" +version = "0.6.5" +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 = "ring" -version = "0.13.2" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -867,16 +1044,16 @@ name = "rust-crypto" version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.9" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -894,13 +1071,16 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "safemem" -version = "0.3.0" +name = "same-file" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "scoped-tls" @@ -927,85 +1107,87 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.78" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.78" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.27" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "sha2" -version = "0.6.0" +name = "sha-1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "slab" -version = "0.3.0" +name = "sha2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "slab" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "smallvec" -version = "0.2.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.5" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "socket2" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (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 = "srp" -version = "0.2.5" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1014,51 +1196,28 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.14.9" +name = "string" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (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.4" +version = "0.15.29" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (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 = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "synstructure" -version = "0.9.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1076,7 +1235,7 @@ name = "syntex_errors" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_pos 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1098,7 +1257,7 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "syntex_errors 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1107,11 +1266,6 @@ dependencies = [ "unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "take" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "term" version = "0.4.6" @@ -1126,47 +1280,51 @@ name = "thread_local" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "time" -version = "0.1.40" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio" -version = "0.1.8" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-codec" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1174,169 +1332,166 @@ name = "tokio-core" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-current-thread" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-fs" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-proto" -version = "0.1.1" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-reactor" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (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)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio-service" -version = "0.1.0" +name = "tokio-sync" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-tcp" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-threadpool" -version = "0.1.6" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.6" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-trace-core" +version = "0.1.0" +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 = "tokio-udp" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-uds" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "try-lock" -version = "0.1.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1345,17 +1500,14 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "ucd-util" +name = "ucd-trie" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "unicase" -version = "2.1.0" +name = "ucd-util" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "unicode-bidi" @@ -1367,32 +1519,22 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "unicode-xid" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "unicode-xid" -version = "0.0.4" -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 = "untrusted" version = "0.6.2" @@ -1400,7 +1542,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "url" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1410,7 +1552,7 @@ dependencies = [ [[package]] name = "utf8-ranges" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1418,28 +1560,42 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "version_check" -version = "0.1.4" +name = "uuid" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.89 (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 = "walkdir" +version = "2.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "want" -version = "0.0.4" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1449,7 +1605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.5" +version = "0.3.6" 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)", @@ -1466,6 +1622,14 @@ name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1481,173 +1645,189 @@ dependencies = [ ] [metadata] -"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" -"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a" -"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" +"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" +"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" +"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" +"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum block-buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1339a1042f5d9f295737ad4d9a6ab6bf81c84a933dba110b9200cd6d1448b814" +"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab" +"checksum block-buffer 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49665c62e0e700857531fa5d3763e91b539ff1abeebd56808d378b495870d60d" +"checksum block-padding 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d75255892aeb580d3c566f213a2b6fdc1c66667839f45719ee1d30ebf2aea591" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" -"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" -"checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" -"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" +"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +"checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" +"checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" "checksum chacha20-poly1305-aead 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77d2058ba29594f69c75e8a9018e0485e3914ca5084e3613cd64529042f5423b" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" -"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" -"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" -"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" -"checksum digest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e5b29bf156f3f4b3c4f610a25ff69370616ae6e0657d416de22645483e72af0a" -"checksum erased-serde 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e030c95ae4adbadad4024871621e9910d8b156a61c4f83a885f28597b294b146" -"checksum eui48 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4970a61eb89c625299a850532620d811b70afac4cd8304cb2e9bf7e63e83ad56" -"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" -"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" +"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" +"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" +"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" +"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" +"checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" +"checksum erased-serde 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" +"checksum eui48 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8c4cf866e4d3e5e773691f5f61615a224a7b0b72b7daf994fc56d1b82dab0b6b" +"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 fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" +"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 fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "0c84b40c7e2de99ffd70602db314a7a8c26b2b3d830e6f7f7a142a8860ab3ca4" +"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb" -"checksum generic-array 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "fceb69994e330afed50c93524be68c42fa898c2d9fd4ee8da03bd7363acd26f2" +"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" +"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" +"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum handlebars 0.32.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d89ec99d1594f285d4590fc32bac5f75cdab383f1123d504d27862c644a807dd" -"checksum httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7b6288d7db100340ca12873fd4d08ad1b8f206a9457798dfb17c018a33fee540" -"checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" +"checksum h2 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "910a5e7be6283a9c91b3982fa5188368c8719cce2a3cf3b86048673bf9d9c36b" +"checksum handlebars 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d82e5750d8027a97b9640e3fefa66bbaf852a35228e1c90790efd13c4b09c166" +"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" +"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum hyper 0.12.25 (registry+https://github.com/rust-lang/crates.io-index)" = "7d5b6658b016965ae301fa995306db965c93677880ea70765a84235a96eae896" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum ipnetwork 0.12.8 (registry+https://github.com/rust-lang/crates.io-index)" = "70783119ac90828aaba91eae39db32c6c1b8838deea3637e5238efa0130801ab" +"checksum ipnetwork 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3d862c86f7867f19b693ec86765e0252d82e53d4240b9b629815675a0714ad1" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" -"checksum lazycell 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e26d4c411b39f0afcf2ba6fe502be90e6c9b299c952dbd86124782520a13cffd" -"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" +"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" +"checksum libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)" = "aab692d7759f5cd8c859e169db98ae5b52c924add2af5fbbca11d12fefb567c1" "checksum libmdns 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10a5de2d38a254122ddb711aa0a5d48ffc501efe7cba4be7ea531b80a274bc0d" -"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" +"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" +"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.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d" +"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4b082692d3f6cf41b453af73839ce3dfc212c4411cbb2441dff80a716e38bd79" "checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum multimap 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb04b9f127583ed176e163fb9ec6f3e793b87e21deedd5734a69386a18a0151" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fd5681d13fda646462cfbd4e5f2051279a89a544d50eb98c365b507246839f" -"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" -"checksum num-complex 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" +"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" +"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" +"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" +"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" -"checksum num-rational 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" +"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" -"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" -"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c" +"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" +"checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" +"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc" -"checksum pest_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3294f437119209b084c797604295f40227cffa35c57220b1e99a6ff3bf8ee4" -"checksum pnet 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3961c514be0c95233bdccdee9831aadd887a889ebc22e57d73e14d1cedb670" -"checksum pnet_base 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "948dbdd36f46888ada1d497703e6cae53d227ab0e8871638aba492ad1e4a76dc" -"checksum pnet_datalink 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8d3b3dd76a11ad99d92fef54b2489f76f4045ebd5251bd1af485d55a7e13db6" -"checksum pnet_macros 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d228096fd739d4e3e60dee9e1e4f07d9ae0f3f309c876834192538748e561e4" -"checksum pnet_macros_support 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f92b7141318df140dfb8c3f7a1a5a331edb31b1791633cc5c8f03fcd9a7f6ac4" -"checksum pnet_packet 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef99f3cfa2c0ed07e9ad6d9f788592d863361a8dd3102989d79b0f6a787ba434" -"checksum pnet_sys 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "963b9109a05c3ac370abc3fda61bff20d03743c2947942173871b9cac2b9acb0" -"checksum pnet_transport 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "568a118fe2f74ebb08e9b9b6ac812b9730a7b043c5ca4d97325f4edeb018cae0" -"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901" +"checksum pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "54f0c72a98d8ab3c99560bfd16df8059cc10e1f9a8e83e6e3b97718dd766e9c3" +"checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +"checksum pest_generator 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646" +"checksum pest_meta 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f5a3492a4ed208ffc247adcdcc7ba2a95be3104f58877d0d02f0df39bf3efb5e" +"checksum pnet 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "63d693c84430248366146e3181ff9d330243464fa9e6146c372b2f3eb2e2d8e7" +"checksum pnet_base 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4df28acf2fcc77436dd2b91a9a0c2bb617f9ca5f2acefee1a4135058b9f9801f" +"checksum pnet_datalink 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b34f8ca857599d05b6b082e9baff8d27c54cb9c26568cf3c0993a5755816966" +"checksum pnet_macros 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f16d1fa7fd0edebc36055587b8b5af8a109bbc29a55fb484a37e2029b971a7" +"checksum pnet_macros_support 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84684f2cddefc37a06f2fe2ca4dcc3457fc3b282734b5246507d8ee75d2780ae" +"checksum pnet_packet 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a6cdcdaddc5174f18286298842a4e31cd3cc018933d42af51434b1fa07dcbe" +"checksum pnet_sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "682b2eca84cc440bce8336813f78eb6d3cb0fed89fe0e87ae22acfca8363f176" +"checksum pnet_transport 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5faa55dcf725487a699adcff88dfea8f17ea34fa2640528866d9acbb4e3a104f" +"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" -"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" -"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" -"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" -"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341" -"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" -"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" -"checksum ring 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe642b9dd1ba0038d78c4a3999d1ee56178b4d415c1e1fbaba83b06dce012f0" +"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" +"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" +"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"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_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" +"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_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.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" +"checksum regex 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee84f70c8c08744ea9641a731c7fadb475bf2ecc52d7f627feb833e0b3990467" +"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" +"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum route-recognizer 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3255338088df8146ba63d60a9b8e3556f1146ce2973bc05a75181a42ce2256" "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" -"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" +"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" +"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "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 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)" = "92ec94e2754699adddbbc4f555791bd3acc2a2f5574cba16c93a4a9cf4a04415" -"checksum serde_derive 1.0.78 (registry+https://github.com/rust-lang/crates.io-index)" = "0fb622d85245add5327d4f08b2d24fd51fa5d35fe1bba19ee79a1f211e9ac0ff" -"checksum serde_json 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "59790990c5115d16027f00913e2e66de23a51f70422e549d2ad68c8c5f268f1c" -"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum serde 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "92514fb95f900c9b5126e32d020f5c6d40564c27a5ea6d1d7d9f157a96623560" +"checksum serde_derive 1.0.89 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6eabf4b5914e88e24eea240bb7c9f9a2cbc1bbbe8d961d381975ec3c6b806c" +"checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" +"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded" +"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" +"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" "checksum socket2 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b4896961171cd3317c7e9603d88f379f8c6e45342212235d356496680c68fd" -"checksum srp 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2d84784d36d23a68279bc131e9c9839ee371bf8b40ecec1614b3ca08f5a8bd5f" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum srp 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b13595b0dae579940388e92965acde7466c3e0053624dbff3a2e829d736bee3" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -"checksum syn 0.15.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9056ebe7f2d6a38bc63171816fd1d3430da5a43896de21676dc5c0a4b8274a11" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" +"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" +"checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" +"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum syntex 0.42.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0a30b08a6b383a22e5f6edc127d169670d48f905bb00ca79a00ea3e442ebe317" "checksum syntex_errors 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04c48f32867b6114449155b2a82114b86d4b09e1bddb21c47ff104ab9172b646" "checksum syntex_pos 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd49988e52451813c61fecbe9abb5cfd4e1b7bb6cdbb980a6fbcbab859171a6" "checksum syntex_syntax 0.42.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7628a0506e8f9666fdabb5f265d0059b059edac9a3f810bda077abb5d826bd8d" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" -"checksum tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fbb6a6e9db2702097bfdfddcb09841211ad423b86c75b5ddaca1d62842ac492c" -"checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb" +"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" +"checksum tokio 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1021bb1f4150435ab8f222eb7ed37c60b2d57037def63ba43085a79f387512d7" +"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdfb899688ac16f618076bd09215edbfda0fd5dfecb375b6942636cb31fa8a7" -"checksum tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84823b932d566bc3c6aa644df4ca36cb38593c50b7db06011fd4e12e31e4047e" -"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135" -"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" -"checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea" -"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -"checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565" -"checksum tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a5758cecb6e0633cea5d563ac07c975e04961690b946b04fd84e7d6445a8f6af" -"checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c" -"checksum tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" -"checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89" -"checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" +"checksum tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c756b04680eea21902a46fca4e9f410a2332c04995af590e07ff262e2193a9a3" +"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" +"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" +"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" +"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" +"checksum tokio-sync 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fda385df506bf7546e70872767f71e81640f1f251bdf2fd8eb81a0eaec5fe022" +"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" +"checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801" +"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" +"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3" +"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" +"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" +"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" -"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" +"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77" +"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" +"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" "checksum unicode-xid 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "36dff09cafb4ec7c8cf0023eb0b686cb6ce65499116a12201c9e11840ca01beb" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "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 untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" -"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" +"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" +"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" "checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22" -"checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" +"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" +"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" +"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd" +"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/Cargo.toml b/Cargo.toml index f4f091f..bd10fe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,42 +1,42 @@ [package] name = "hap" -version = "0.0.3" -authors = ["Elias Wilken "] +version = "0.0.4" +edition = "2018" +authors = ["Elias Wilken "] description = "Rust implementation of the Apple HomeKit Accessory Protocol (HAP)" repository = "https://github.com/ewilken/hap-rs" readme = "README.md" license = "MIT/Apache-2.0" [dependencies] -eui48 = "0.3.0" -rand = "0.4" -uuid = { version = "0.5.1", features = ["v4", "serde"] } -serde = { version = "1.0.27", features = ["rc"] } -serde_derive = "1.0.27" -serde_json = "1.0.9" -bytes = "0.4.6" -byteorder = "1.2.1" +eui48 = "0.4.6" +rand = "0.6.5" +uuid = { version = "0.7.2", features = ["v4", "serde"] } +serde = { version = "1.0.87", features = ["rc"] } +serde_derive = "1.0.87" +serde_json = "1.0.38" +bytes = "0.4.11" +byteorder = "1.3.1" rust-crypto = "0.2.36" -futures = "0.1.17" -hyper = "0.11.18" +futures = "0.1.25" +hyper = "0.12.24" route-recognizer = "0.1.12" -libmdns = "0.2.2" -srp = "0.2.4" -sha2 = "0.6.0" -pnet = "0.21.0" -num = "0.1.41" -ring = "0.13" +libmdns = "0.2.3" +srp = "0.4.0" +sha2 = "0.8.0" +pnet = "0.22.0" +num = "0.2.0" +ring = "0.14.6" chacha20-poly1305-aead = "0.1.2" -tokio-core = "0.1.17" -tokio-io = "0.1.6" -erased-serde = "0.3.3" -url = "1.7.0" -failure = "0.1.1" -log = "0.4.4" +tokio = "0.1.15" +erased-serde = "0.3.9" +url = "1.7.2" +failure = "0.1.5" +log = "0.4.6" [build-dependencies] uuid = { version = "0.5.1", features = ["v4", "serde"] } -handlebars = "0.32.1" -serde = "1.0.27" -serde_derive = "1.0.27" -serde_json = "1.0.9" +handlebars = "1.1.0" +serde = "1.0.87" +serde_derive = "1.0.87" +serde_json = "1.0.38" diff --git a/LICENSE-MIT b/LICENSE-MIT index 48313d3..c541f9f 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018 Elias Wilken +Copyright (c) 2019 Elias Wilken Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/README.md b/README.md index 6bff055..1b79ae4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![docs](https://docs.rs/hap/badge.svg)](https://docs.rs/hap) [![license: MIT/Apache-2.0](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](https://github.com/ewilken/hap-rs) -Rust implementation of the Apple HomeKit Accessory Protocol (HAP) based on [Tokio](https://github.com/tokio-rs/tokio) and [Hyper](https://github.com/hyperium/hyper). +Rust implementation of the Apple HomeKit Accessory Protocol (HAP). This crate supports all HomeKit Services and Characteristics currently implemented by Apple and provides the ability to create custom Characteristics, Services and Accessories. @@ -50,8 +50,6 @@ For a full list of the predefined Characteristics, Services and Accessories, see Creating a simple outlet Accessory and starting the IP transport: ```rust -extern crate hap; - use hap::{ transport::{Transport, IpTransport}, accessory::{Category, Information, outlet}, @@ -81,8 +79,6 @@ fn main() { Dynamically adding and removing Accessories: ```rust -extern crate hap; - use hap::{ transport::{Transport, IpTransport}, accessory::{Category, Information, bridge, outlet}, @@ -124,8 +120,6 @@ fn main() { Using the `Readable` and `Updatable` traits to react to remote value reads and updates: ```rust -extern crate hap; - use hap::{ transport::{Transport, IpTransport}, accessory::{Category, Information, outlet}, @@ -188,8 +182,6 @@ Change dependent Characteristics on value changes: ```rust use std::{rc::Rc, cell::RefCell}; -extern crate hap; - use hap::{ transport::{Transport, IpTransport}, accessory::{Category, Information, door}, @@ -205,13 +197,13 @@ pub struct VirtualDoorInner { #[derive(Clone)] pub struct VirtualDoor { - inner: Rc>, + inner: Arc>, current_position: Characteristic, } impl VirtualDoor { pub fn new(inner: VirtualDoorInner, current_position: Characteristic) -> VirtualDoor { - VirtualDoor { inner: Rc::new(RefCell::new(inner)), current_position } + VirtualDoor { inner: Arc::new(Mutex::new(inner)), current_position } } } diff --git a/build.rs b/build.rs index 919c97e..4fd0303 100644 --- a/build.rs +++ b/build.rs @@ -1,12 +1,18 @@ -extern crate uuid; extern crate handlebars; extern crate serde; -#[macro_use] extern crate serde_json; -#[macro_use] extern crate serde_derive; - -use std::{fs::{self, File}, io::Write, collections::HashMap}; +extern crate uuid; +#[macro_use] +extern crate serde_json; +#[macro_use] +extern crate serde_derive; + +use std::{ + collections::HashMap, + fs::{self, File}, + io::Write, +}; -use handlebars::{Handlebars, Helper, RenderContext, RenderError, Renderable}; +use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError, Renderable}; #[derive(Debug, Serialize, Deserialize)] struct Metadata { @@ -70,163 +76,309 @@ struct Service { pub optional_characteristics: Vec, } -fn if_eq_helper(h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn if_eq_helper<'reg, 'rc>( + h: &Helper<'reg, 'rc>, + r: &'reg Handlebars, + c: &Context, + rc: &mut RenderContext<'reg>, + out: &mut Output, +) -> Result<(), RenderError> { let first = h.param(0).unwrap().value(); let second = h.param(1).unwrap().value(); let tmpl = if first == second { h.template() } else { h.inverse() }; match tmpl { - Some(ref t) => t.render(r, rc), + Some(ref t) => t.render(r, c, rc, out), None => Ok(()), } } -fn trim_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn trim_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { let trim = s.replace(" ", "").replace(".", "_"); - try!(rc.writer.write(&trim.into_bytes())); + out.write(&trim)?; } Ok(()) } -fn file_name_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn file_name_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { let name = s.replace(" ", "_").replace(".", "_").to_lowercase(); - try!(rc.writer.write(&name.into_bytes())); + out.write(&name)?; } Ok(()) } -fn type_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn type_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { match s { - "bool" => { try!(rc.writer.write(b"bool")); }, - "uint8" => { try!(rc.writer.write(b"u8")); }, - "uint16" => { try!(rc.writer.write(b"u16")); }, - "uint32" => { try!(rc.writer.write(b"u32")); }, - "uint64" => { try!(rc.writer.write(b"u64")); }, - "int" => { try!(rc.writer.write(b"i32")); }, - "int32" => { try!(rc.writer.write(b"i32")); }, - "float" => { try!(rc.writer.write(b"f32")); }, - "string" => { try!(rc.writer.write(b"String")); }, - "tlv8" => { try!(rc.writer.write(b"Vec")); }, - "data" => { try!(rc.writer.write(b"Vec")); }, - _ => { return Err(RenderError::new("Unknown Characteristic format")); }, + "bool" => { + out.write("bool")?; + }, + "uint8" => { + out.write("u8")?; + }, + "uint16" => { + out.write("u16")?; + }, + "uint32" => { + out.write("u32")?; + }, + "uint64" => { + out.write("u64")?; + }, + "int" => { + out.write("i32")?; + }, + "int32" => { + out.write("i32")?; + }, + "float" => { + out.write("f32")?; + }, + "string" => { + out.write("String")?; + }, + "tlv8" => { + out.write("Vec")?; + }, + "data" => { + out.write("Vec")?; + }, + _ => { + return Err(RenderError::new("Unknown Characteristic format")); + }, } } Ok(()) } -fn format_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn format_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { match s { - "bool" => { try!(rc.writer.write(b"Format::Bool")); }, - "uint8" => { try!(rc.writer.write(b"Format::UInt8")); }, - "uint16" => { try!(rc.writer.write(b"Format::UInt16")); }, - "uint32" => { try!(rc.writer.write(b"Format::UInt32")); }, - "uint64" => { try!(rc.writer.write(b"Format::UInt64")); }, - "int" => { try!(rc.writer.write(b"Format::Int32")); }, - "int32" => { try!(rc.writer.write(b"Format::Int32")); }, - "float" => { try!(rc.writer.write(b"Format::Float")); }, - "string" => { try!(rc.writer.write(b"Format::String")); }, - "tlv8" => { try!(rc.writer.write(b"Format::Tlv8")); }, - "data" => { try!(rc.writer.write(b"Format::Data")); }, - _ => { return Err(RenderError::new("Unknown Characteristic format")); }, + "bool" => { + out.write("Format::Bool")?; + }, + "uint8" => { + out.write("Format::UInt8")?; + }, + "uint16" => { + out.write("Format::UInt16")?; + }, + "uint32" => { + out.write("Format::UInt32")?; + }, + "uint64" => { + out.write("Format::UInt64")?; + }, + "int" => { + out.write("Format::Int32")?; + }, + "int32" => { + out.write("Format::Int32")?; + }, + "float" => { + out.write("Format::Float")?; + }, + "string" => { + out.write("Format::String")?; + }, + "tlv8" => { + out.write("Format::Tlv8")?; + }, + "data" => { + out.write("Format::Data")?; + }, + _ => { + return Err(RenderError::new("Unknown Characteristic format")); + }, } } Ok(()) } -fn unit_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn unit_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { match s { - "percentage" => { try!(rc.writer.write(b"Unit::Percentage")); }, - "arcdegrees" => { try!(rc.writer.write(b"Unit::ArcDegrees")); }, - "celsius" => { try!(rc.writer.write(b"Unit::Celsius")); }, - "lux" => { try!(rc.writer.write(b"Unit::Lux")); }, - "seconds" => { try!(rc.writer.write(b"Unit::Seconds")); }, - _ => { return Err(RenderError::new("Unknown Characteristic unit")); }, + "percentage" => { + out.write("Unit::Percentage")?; + }, + "arcdegrees" => { + out.write("Unit::ArcDegrees")?; + }, + "celsius" => { + out.write("Unit::Celsius")?; + }, + "lux" => { + out.write("Unit::Lux")?; + }, + "seconds" => { + out.write("Unit::Seconds")?; + }, + _ => { + return Err(RenderError::new("Unknown Characteristic unit")); + }, } } Ok(()) } -fn uuid_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn uuid_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value(); if let Some(s) = param.as_str() { - try!(rc.writer.write(shorten_uuid(&s).as_bytes())); + out.write(&shorten_uuid(&s))?; } Ok(()) } -fn valid_values_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn valid_values_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value().as_object().unwrap(); let mut output = String::from("vec![\n"); for (key, val) in param { output.push_str(&format!("\t\t\t{}, // {}\n", key, val)); } output.push_str("\t\t]"); - try!(rc.writer.write(output.as_bytes())); + out.write(&output)?; Ok(()) } -fn perms_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn perms_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let params = h.param(0).unwrap().value().as_array().unwrap(); for param in params { match param.as_str() { - Some("read") => { try!(rc.writer.write(b"\n\t\t\tPerm::PairedRead,")); }, - Some("write") => { try!(rc.writer.write(b"\n\t\t\tPerm::PairedWrite,")); }, - Some("cnotify") => { try!(rc.writer.write(b"\n\t\t\tPerm::Events,")); }, + Some("read") => { + out.write("\n\t\t\tPerm::PairedRead,")?; + }, + Some("write") => { + out.write("\n\t\t\tPerm::PairedWrite,")?; + }, + Some("cnotify") => { + out.write("\n\t\t\tPerm::Events,")?; + }, _ => {}, } } Ok(()) } -fn float_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn float_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let format = h.param(0).unwrap().value().as_str().unwrap(); if format == "float" { - try!(rc.writer.write(b" as f32")); + out.write(" as f32")?; } Ok(()) } fn shorten_uuid(id: &str) -> String { - id.split("-").collect::>()[0].trim_left_matches('0').to_owned() -} - -fn characteristic_name_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { + id.split("-").collect::>()[0] + .trim_start_matches('0') + .to_owned() +} + +fn characteristic_name_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let id = h.param(0).unwrap().value().as_str().unwrap(); let characteristics: Vec = serde_json::from_value(h.param(1).unwrap().value().clone()).unwrap(); for c in characteristics { if &c.id == id { let name = c.name.replace(" ", "").replace(".", "_"); - try!(rc.writer.write(name.as_bytes())); + out.write(&name)?; } } Ok(()) } -fn characteristic_file_name_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn characteristic_file_name_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let id = h.param(0).unwrap().value().as_str().unwrap(); let characteristics: Vec = serde_json::from_value(h.param(1).unwrap().value().clone()).unwrap(); for c in characteristics { if &c.id == id { let name = c.name.replace(" ", "_").replace(".", "_").to_lowercase(); - try!(rc.writer.write(name.as_bytes())); + out.write(&name)?; } } Ok(()) } -fn snake_case_helper(h: &Helper, _: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> { +fn snake_case_helper( + h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut Output, +) -> Result<(), RenderError> { let param = h.param(0).unwrap().value().as_str().unwrap(); let name = param.replace(" ", "_").replace(".", "_").to_lowercase(); - try!(rc.writer.write(name.as_bytes())); + out.write(&name)?; Ok(()) } @@ -282,7 +434,7 @@ impl Serialize for HapType { "; static CHARACTERISTIC: &'static str = "// THIS FILE IS AUTO-GENERATED\n -use characteristic::{HapType, Characteristic, Inner, Format, Perm{{#if characteristic.Unit}}, Unit{{/if}}}; +use crate::characteristic::{HapType, Characteristic, Inner, Format, Perm{{#if characteristic.Unit}}, Unit{{/if}}}; /// {{characteristic.Name}} Characteristic. pub type {{trim characteristic.Name}} = Characteristic<{{type characteristic.Format}}>; @@ -295,12 +447,12 @@ pub fn new() -> {{trim characteristic.Name}} { perms: vec![{{perms characteristic.Properties}} ],\ {{#if characteristic.Unit}}\n\t\tunit: Some({{unit characteristic.Unit}}),{{/if}}\ - {{#if characteristic.Constraints.MaximumValue}}\n\t\tmax_value: Some({{characteristic.Constraints.MaximumValue}}{{float characteristic.Format}}),{{/if}}\ - {{#if characteristic.Constraints.MinimumValue}}\n\t\tmin_value: Some({{characteristic.Constraints.MinimumValue}}{{float characteristic.Format}}),{{/if}}\ - {{#if characteristic.Constraints.StepValue}}\n\t\tstep_value: Some({{characteristic.Constraints.StepValue}}{{float characteristic.Format}}),{{/if}}\ - {{#if characteristic.Constraints.MaximumLength}}\n\t\tmax_len: Some({{characteristic.Constraints.MaximumLength}}{{float characteristic.Format}}),{{/if}}\ - {{#if characteristic.Constraints.MaximumDataLength}}\n\t\tmax_data_len: Some({{characteristic.Constraints.MaximumDataLength}}{{float characteristic.Format}}),{{/if}}\ - {{#if characteristic.Constraints.ValidValues}}\n\t\tvalid_values: Some({{valid_values characteristic.Constraints.ValidValues}}),{{/if}} + {{#if characteristic.Constraints.MaximumValue includeZero=true}}\n\t\tmax_value: Some({{characteristic.Constraints.MaximumValue}}{{float characteristic.Format}}),{{/if}}\ + {{#if characteristic.Constraints.MinimumValue includeZero=true}}\n\t\tmin_value: Some({{characteristic.Constraints.MinimumValue}}{{float characteristic.Format}}),{{/if}}\ + {{#if characteristic.Constraints.StepValue includeZero=true}}\n\t\tstep_value: Some({{characteristic.Constraints.StepValue}}{{float characteristic.Format}}),{{/if}}\ + {{#if characteristic.Constraints.MaximumLength includeZero=true}}\n\t\tmax_len: Some({{characteristic.Constraints.MaximumLength}}{{float characteristic.Format}}),{{/if}}\ + {{#if characteristic.Constraints.MaximumDataLength includeZero=true}}\n\t\tmax_data_len: Some({{characteristic.Constraints.MaximumDataLength}}{{float characteristic.Format}}),{{/if}}\ + {{#if characteristic.Constraints.ValidValues includeZero=true}}\n\t\tvalid_values: Some({{valid_values characteristic.Constraints.ValidValues}}),{{/if}} ..Default::default() }) } @@ -311,25 +463,27 @@ static CHARACTERISTIC_MOD: &'static str = "// THIS FILE IS AUTO-GENERATED "; static SERVICE: &'static str = "// THIS FILE IS AUTO-GENERATED\n -use service::{HapService, Service}; -use characteristic::{ - HapCharacteristic, +use crate::{ + service::{HapService, Service}, + characteristic::{ + HapCharacteristic, {{#each service.RequiredCharacteristics as |r|}}\ {{#each ../this.characteristics as |c|}}\ {{#if_eq r c.UUID}}\ -\t{{characteristic_file_name r ../../this.characteristics}}, +\t\t{{characteristic_file_name r ../../this.characteristics}}, {{/if_eq}}\ {{/each}}\ {{/each}}\ {{#each service.OptionalCharacteristics as |r|}}\ {{#each ../this.characteristics as |c|}}\ {{#if_eq r c.UUID}}\ -\t{{characteristic_file_name r ../../this.characteristics}}, +\t\t{{characteristic_file_name r ../../this.characteristics}}, {{/if_eq}}\ {{/each}}\ {{/each}}\ +\t}, + HapType, }; -use HapType; /// {{service.Name}} Service. pub type {{trim service.Name}} = Service<{{trim service.Name}}Inner>; @@ -463,11 +617,12 @@ static SERVICE_MOD: &'static str = "// THIS FILE IS AUTO-GENERATED "; static ACCESSORY: &'static str = "// THIS FILE IS AUTO-GENERATED\n -use accessory::{HapAccessory, HapAccessoryService, Accessory, Information}; -use service::{HapService, accessory_information::AccessoryInformation, {{snake_case service.Name}}}; -use event::EmitterPtr; - -use Error; +use crate::{ +\taccessory::{HapAccessory, HapAccessoryService, Accessory, Information}, +\tservice::{HapService, accessory_information::AccessoryInformation, {{snake_case service.Name}}}, +\tevent::EmitterPtr, +\tError, +}; /// {{service.Name}} Accessory. pub type {{trim service.Name}} = Accessory<{{trim service.Name}}Inner>; @@ -563,12 +718,18 @@ fn main() { handlebars.register_helper("snake_case", Box::new(snake_case_helper)); handlebars.register_template_string("categories", CATEGORIES).unwrap(); handlebars.register_template_string("hap_type", HAP_TYPE).unwrap(); - handlebars.register_template_string("characteristic", CHARACTERISTIC).unwrap(); - handlebars.register_template_string("characteristic_mod", CHARACTERISTIC_MOD).unwrap(); + handlebars + .register_template_string("characteristic", CHARACTERISTIC) + .unwrap(); + handlebars + .register_template_string("characteristic_mod", CHARACTERISTIC_MOD) + .unwrap(); handlebars.register_template_string("service", SERVICE).unwrap(); handlebars.register_template_string("service_mod", SERVICE_MOD).unwrap(); handlebars.register_template_string("accessory", ACCESSORY).unwrap(); - handlebars.register_template_string("accessory_mod", ACCESSORY_MOD).unwrap(); + handlebars + .register_template_string("accessory_mod", ACCESSORY_MOD) + .unwrap(); let categories = handlebars.render("categories", &metadata).unwrap(); let categories_path = "src/accessory/category.rs".to_owned(); @@ -584,7 +745,9 @@ fn main() { fs::create_dir_all(&characteristics_base_path).unwrap(); let mut characteristsic_names = vec![]; for c in &metadata.characteristics { - let characteristic = handlebars.render("characteristic", &json!({"characteristic": c})).unwrap(); + let characteristic = handlebars + .render("characteristic", &json!({ "characteristic": c })) + .unwrap(); let characteristic_file_name = c.name.replace(" ", "_").replace(".", "_").to_lowercase(); let mut characteristic_path = String::from(characteristics_base_path); characteristic_path.push_str(&characteristic_file_name); @@ -593,9 +756,16 @@ fn main() { characteristic_file.write_all(characteristic.as_bytes()).unwrap(); characteristsic_names.push(characteristic_file_name); } - let characteristic_mod = handlebars.render("characteristic_mod", &json!({"characteristics": characteristsic_names})).unwrap(); + let characteristic_mod = handlebars + .render( + "characteristic_mod", + &json!({ "characteristics": characteristsic_names }), + ) + .unwrap(); let mut characteristic_mod_file = File::create(&format!("{}mod.rs", characteristics_base_path)).unwrap(); - characteristic_mod_file.write_all(characteristic_mod.as_bytes()).unwrap(); + characteristic_mod_file + .write_all(characteristic_mod.as_bytes()) + .unwrap(); let services_base_path = "src/service/includes/"; let accessory_base_path = "src/accessory/includes/"; @@ -604,7 +774,12 @@ fn main() { let mut service_names = vec![]; let mut accessory_names = vec![]; for s in &metadata.services { - let service = handlebars.render("service", &json!({"service": s, "characteristics": &metadata.characteristics})).unwrap(); + let service = handlebars + .render( + "service", + &json!({"service": s, "characteristics": &metadata.characteristics}), + ) + .unwrap(); let service_file_name = s.name.replace(" ", "_").replace(".", "_").to_lowercase(); let mut service_path = String::from(services_base_path); service_path.push_str(&service_file_name); @@ -613,20 +788,26 @@ fn main() { service_file.write_all(service.as_bytes()).unwrap(); service_names.push(service_file_name.clone()); - if s.name != "Accessory Information" && - s.name != "Battery Service" && - s.name != "Camera RTP Stream Management" && - s.name != "Doorbell" && - s.name != "Faucet" && - s.name != "Filter Maintenance" && - s.name != "Irrigation System" && - s.name != "Lock Management" && - s.name != "Lock Mechanism" && - s.name != "Microphone" && - s.name != "Service Label" && - s.name != "Slat" && - s.name != "Speaker" { - let accessory = handlebars.render("accessory", &json!({"service": s, "characteristics": &metadata.characteristics})).unwrap(); + if s.name != "Accessory Information" + && s.name != "Battery Service" + && s.name != "Camera RTP Stream Management" + && s.name != "Doorbell" + && s.name != "Faucet" + && s.name != "Filter Maintenance" + && s.name != "Irrigation System" + && s.name != "Lock Management" + && s.name != "Lock Mechanism" + && s.name != "Microphone" + && s.name != "Service Label" + && s.name != "Slat" + && s.name != "Speaker" + { + let accessory = handlebars + .render( + "accessory", + &json!({"service": s, "characteristics": &metadata.characteristics}), + ) + .unwrap(); let mut accessory_path = String::from(accessory_base_path); accessory_path.push_str(&service_file_name); accessory_path.push_str(".rs"); @@ -635,10 +816,14 @@ fn main() { accessory_names.push(service_file_name); } } - let service_mod = handlebars.render("service_mod", &json!({"services": service_names})).unwrap(); + let service_mod = handlebars + .render("service_mod", &json!({ "services": service_names })) + .unwrap(); let mut service_mod_file = File::create(&format!("{}mod.rs", services_base_path)).unwrap(); service_mod_file.write_all(service_mod.as_bytes()).unwrap(); - let accessory_mod = handlebars.render("accessory_mod", &json!({"accessories": accessory_names})).unwrap(); + let accessory_mod = handlebars + .render("accessory_mod", &json!({ "accessories": accessory_names })) + .unwrap(); let mut accessory_mod_file = File::create(&format!("{}mod.rs", accessory_base_path)).unwrap(); accessory_mod_file.write_all(accessory_mod.as_bytes()).unwrap(); } diff --git a/default.metadata.json b/default.metadata.json index 2c3c7ee..d225f23 100644 --- a/default.metadata.json +++ b/default.metadata.json @@ -81,24 +81,24 @@ "Characteristics": [{ "UUID": "000000A6-0000-1000-8000-0026BB765291", "Name": "Accessory Flags", - "Format": "uint32", "Constraints": { "ValidBits": { "0": "Requires Additional Setup" } }, + "Format": "uint32", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000B0-0000-1000-8000-0026BB765291", "Name": "Active", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Inactive", "1": "Active" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -110,30 +110,29 @@ }, { "UUID": "00000064-0000-1000-8000-0026BB765291", "Name": "Air Particulate Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000065-0000-1000-8000-0026BB765291", "Name": "Air Particulate Size", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "2.5 μm", "1": "10 μm" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000095-0000-1000-8000-0026BB765291", "Name": "Air Quality", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Fair", @@ -144,6 +143,7 @@ "5": "Poor" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -179,71 +179,70 @@ }, { "UUID": "00000092-0000-1000-8000-0026BB765291", "Name": "Carbon Dioxide Detected", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "CO2 Levels Normal", "1": "CO2 Levels Abnormal" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000093-0000-1000-8000-0026BB765291", "Name": "Carbon Dioxide Level", - "Format": "float", "Constraints": { "MaximumValue": 100000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000094-0000-1000-8000-0026BB765291", "Name": "Carbon Dioxide Peak Level", - "Format": "float", "Constraints": { "MaximumValue": 100000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000069-0000-1000-8000-0026BB765291", "Name": "Carbon Monoxide Detected", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "CO Levels Normal", "1": "CO Levels Abnormal" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000090-0000-1000-8000-0026BB765291", "Name": "Carbon Monoxide Level", - "Format": "float", "Constraints": { "MaximumValue": 100, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000091-0000-1000-8000-0026BB765291", "Name": "Carbon Monoxide Peak Level", - "Format": "float", "Constraints": { "MaximumValue": 100, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "0000008F-0000-1000-8000-0026BB765291", "Name": "Charging State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Not Charging", @@ -251,29 +250,30 @@ "2": "Not Chargeable" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000CE-0000-1000-8000-0026BB765291", "Name": "Color Temperature", - "Format": "uint32", "Constraints": { "StepValue": 1, "MaximumValue": 500, "MinimumValue": 140 }, + "Format": "uint32", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "0000006A-0000-1000-8000-0026BB765291", "Name": "Contact Sensor State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Contact Detected", "1": "Contact Not Detected" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -291,7 +291,6 @@ }, { "UUID": "000000A9-0000-1000-8000-0026BB765291", "Name": "Current Air Purifier State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Inactive", @@ -299,6 +298,7 @@ "2": "Purifying Air" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -315,7 +315,6 @@ }, { "UUID": "0000000E-0000-1000-8000-0026BB765291", "Name": "Current Door State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Closing", @@ -325,12 +324,12 @@ "0": "Open" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000AF-0000-1000-8000-0026BB765291", "Name": "Current Fan State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Inactive", @@ -338,12 +337,12 @@ "2": "Blowing Air" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000B1-0000-1000-8000-0026BB765291", "Name": "Current Heater Cooler State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Cooling", @@ -352,12 +351,12 @@ "0": "Inactive" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "0000000F-0000-1000-8000-0026BB765291", "Name": "Current Heating Cooling State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Off", @@ -365,6 +364,7 @@ "2": "Cool" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -382,7 +382,6 @@ }, { "UUID": "000000B3-0000-1000-8000-0026BB765291", "Name": "Current Humidifier Dehumidifier State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Dehumidifying", @@ -391,6 +390,7 @@ "0": "Inactive" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -420,7 +420,6 @@ }, { "UUID": "000000AA-0000-1000-8000-0026BB765291", "Name": "Current Slat State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Fixed", @@ -428,6 +427,7 @@ "2": "Swinging" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -475,24 +475,24 @@ }, { "UUID": "000000AC-0000-1000-8000-0026BB765291", "Name": "Filter Change Indication", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Filter OK", "1": "Change Filter" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000AB-0000-1000-8000-0026BB765291", "Name": "Filter Life Level", - "Format": "float", "Constraints": { "stepValue": 1, "MaximumValue": 100, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -564,37 +564,37 @@ }, { "UUID": "000000D2-0000-1000-8000-0026BB765291", "Name": "In Use", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Not in use", "1": "In use" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000D6-0000-1000-8000-0026BB765291", "Name": "Is Configured", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Not Configured", "1": "Configured" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "00000070-0000-1000-8000-0026BB765291", "Name": "Leak Detected", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Leak Not Detected", "1": "Leak Detected" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -606,7 +606,6 @@ }, { "UUID": "0000001D-0000-1000-8000-0026BB765291", "Name": "Lock Current State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Unknown", @@ -615,12 +614,12 @@ "0": "Unsecured" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "0000001C-0000-1000-8000-0026BB765291", "Name": "Lock Last Known Action", - "Format": "uint8", "Constraints": { "ValidValues": { "7": "Unsecured Remotely", @@ -634,6 +633,7 @@ "2": "Secured Physically, Exterior" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -646,25 +646,25 @@ }, { "UUID": "000000A7-0000-1000-8000-0026BB765291", "Name": "Lock Physical Controls", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Control Lock Disabled", "1": "Control Lock Enabled" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "0000001E-0000-1000-8000-0026BB765291", "Name": "Lock Target State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Unsecured", "1": "Secured" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -712,12 +712,12 @@ }, { "UUID": "000000C4-0000-1000-8000-0026BB765291", "Name": "Nitrogen Dioxide Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -729,13 +729,13 @@ }, { "UUID": "00000071-0000-1000-8000-0026BB765291", "Name": "Occupancy Detected", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Occupancy Not Detected", "1": "Occupancy Detected" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -759,12 +759,12 @@ }, { "UUID": "000000C3-0000-1000-8000-0026BB765291", "Name": "Ozone Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -794,29 +794,28 @@ }, { "UUID": "000000C7-0000-1000-8000-0026BB765291", "Name": "PM10 Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000C6-0000-1000-8000-0026BB765291", "Name": "PM2.5 Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000072-0000-1000-8000-0026BB765291", "Name": "Position State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Decreasing", @@ -824,12 +823,12 @@ "2": "Stopped" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000D1-0000-1000-8000-0026BB765291", "Name": "Program Mode", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "No program scheduled", @@ -837,12 +836,12 @@ "2": "Program scheduled (Manual Mode)" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000073-0000-1000-8000-0026BB765291", "Name": "Programmable Switch Event", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Single Press", @@ -850,6 +849,7 @@ "2": "Long Press" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -879,35 +879,35 @@ }, { "UUID": "000000D4-0000-1000-8000-0026BB765291", "Name": "Remaining Duration", - "Format": "uint32", "Constraints": { "StepValue": 1, "MaximumValue": 3600, "MinimumValue": 0 }, + "Format": "uint32", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000AD-0000-1000-8000-0026BB765291", "Name": "Reset Filter Indication", - "Format": "uint8", "Constraints": { "StepValue": 1, "MaximumValue": 1, "MinimumValue": 1 }, + "Format": "uint8", "Permissions": ["securedWrite"], "Properties": ["write"] }, { "UUID": "00000028-0000-1000-8000-0026BB765291", "Name": "Rotation Direction", - "Format": "int32", "Constraints": { "ValidValues": { "0": "Clockwise", "1": "Counter-clockwise" } }, + "Format": "int32", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -937,18 +937,17 @@ }, { "UUID": "0000008E-0000-1000-8000-0026BB765291", "Name": "Security System Alarm Type", - "Format": "uint8", "Constraints": { "StepValue": 1, "MaximumValue": 1, "MinimumValue": 0 }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000066-0000-1000-8000-0026BB765291", "Name": "Security System Current State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Disarmed", @@ -958,12 +957,12 @@ "0": "Stay Arm" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000067-0000-1000-8000-0026BB765291", "Name": "Security System Target State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Disarm", @@ -972,6 +971,7 @@ "0": "Stay Arm" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -983,44 +983,44 @@ }, { "UUID": "00000030-0000-1000-8000-0026BB765291", "Name": "Serial Number", - "Format": "string", "Constraints": { "MaximumLength": 64 }, + "Format": "string", "Permissions": ["securedRead"], "Properties": ["read"] }, { "UUID": "000000CB-0000-1000-8000-0026BB765291", "Name": "Service Label Index", - "Format": "uint8", "Constraints": { "StepValue": 1, "MaximumValue": 255, "MinimumValue": 1 }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read"] }, { "UUID": "000000CD-0000-1000-8000-0026BB765291", "Name": "Service Label Namespace", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Dots", "1": "Arabic Numerals" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read"] }, { "UUID": "000000D3-0000-1000-8000-0026BB765291", "Name": "Set Duration", - "Format": "uint32", "Constraints": { "StepValue": 1, "MaximumValue": 3600, "MinimumValue": 0 }, + "Format": "uint32", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -1032,25 +1032,25 @@ }, { "UUID": "000000C0-0000-1000-8000-0026BB765291", "Name": "Slat Type", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Horizontal", "1": "Vertical" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read"] }, { "UUID": "00000076-0000-1000-8000-0026BB765291", "Name": "Smoke Detected", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Smoke Not Detected", "1": "Smoke Detected" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -1062,49 +1062,49 @@ }, { "UUID": "00000077-0000-1000-8000-0026BB765291", "Name": "Status Fault", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "No Fault", "1": "General Fault" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000078-0000-1000-8000-0026BB765291", "Name": "Status Jammed", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Not Jammed", "1": "Jammed" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000079-0000-1000-8000-0026BB765291", "Name": "Status Low Battery", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Battery Level Normal", "1": "Battery Level Low" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "0000007A-0000-1000-8000-0026BB765291", "Name": "Status Tampered", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Not Tampered", "1": "Tampered" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -1116,12 +1116,12 @@ }, { "UUID": "000000C5-0000-1000-8000-0026BB765291", "Name": "Sulphur Dioxide Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -1145,31 +1145,30 @@ }, { "UUID": "000000B6-0000-1000-8000-0026BB765291", "Name": "Swing Mode", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Swing Disabled", "1": "Swing Enabled" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "000000A8-0000-1000-8000-0026BB765291", "Name": "Target Air Purifier State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Manual", "1": "Auto" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "000000AE-0000-1000-8000-0026BB765291", "Name": "Target Air Quality", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Excellent", @@ -1177,36 +1176,36 @@ "2": "Fair" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "00000032-0000-1000-8000-0026BB765291", "Name": "Target Door State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Open", "1": "Closed" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "000000BF-0000-1000-8000-0026BB765291", "Name": "Target Fan State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Manual", "1": "Auto" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "000000B2-0000-1000-8000-0026BB765291", "Name": "Target Heater Cooler State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Auto", @@ -1214,12 +1213,12 @@ "2": "Cool" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "00000033-0000-1000-8000-0026BB765291", "Name": "Target Heating Cooling State", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Auto", @@ -1228,6 +1227,7 @@ "0": "Off" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -1245,7 +1245,6 @@ }, { "UUID": "000000B4-0000-1000-8000-0026BB765291", "Name": "Target Humidifier Dehumidifier State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Humidifier or Dehumidifier", @@ -1253,6 +1252,7 @@ "2": "Dehumidifier" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -1282,13 +1282,13 @@ }, { "UUID": "000000BE-0000-1000-8000-0026BB765291", "Name": "Target Slat State", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Manual", "1": "Auto" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { @@ -1330,19 +1330,18 @@ }, { "UUID": "00000036-0000-1000-8000-0026BB765291", "Name": "Temperature Display Units", - "Format": "uint8", "Constraints": { "ValidValues": { "0": "Celsius", "1": "Fahrenheit" } }, + "Format": "uint8", "Permissions": ["securedRead", "securedWrite"], "Properties": ["read", "write", "cnotify", "uncnotify"] }, { "UUID": "000000D5-0000-1000-8000-0026BB765291", "Name": "Valve Type", - "Format": "uint8", "Constraints": { "ValidValues": { "3": "Water faucet", @@ -1351,26 +1350,27 @@ "0": "Generic valve" } }, + "Format": "uint8", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "00000037-0000-1000-8000-0026BB765291", "Name": "Version", - "Format": "string", "Constraints": { "MaximumLength": 64 }, + "Format": "string", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { "UUID": "000000C8-0000-1000-8000-0026BB765291", "Name": "VOC Density", - "Format": "float", "Constraints": { "StepValue": 1, "MaximumValue": 1000, "MinimumValue": 0 }, + "Format": "float", "Permissions": ["securedRead"], "Properties": ["read", "cnotify", "uncnotify"] }, { @@ -1399,203 +1399,203 @@ }], "Version": "1.0", "Services": [{ - "RequiredCharacteristics": ["00000014-0000-1000-8000-0026BB765291", "00000020-0000-1000-8000-0026BB765291", "00000021-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "00000030-0000-1000-8000-0026BB765291", "00000052-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000053-0000-1000-8000-0026BB765291", "000000A6-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000014-0000-1000-8000-0026BB765291", "00000020-0000-1000-8000-0026BB765291", "00000021-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "00000030-0000-1000-8000-0026BB765291", "00000052-0000-1000-8000-0026BB765291"], "Name": "Accessory Information", "UUID": "0000003E-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000A9-0000-1000-8000-0026BB765291", "000000A8-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000A7-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "000000B6-0000-1000-8000-0026BB765291", "00000029-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000A9-0000-1000-8000-0026BB765291", "000000A8-0000-1000-8000-0026BB765291"], "Name": "Air Purifier", "UUID": "000000BB-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000095-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "000000C3-0000-1000-8000-0026BB765291", "000000C4-0000-1000-8000-0026BB765291", "000000C5-0000-1000-8000-0026BB765291", "000000C6-0000-1000-8000-0026BB765291", "000000C7-0000-1000-8000-0026BB765291", "000000C8-0000-1000-8000-0026BB765291", "00000090-0000-1000-8000-0026BB765291", "00000093-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000095-0000-1000-8000-0026BB765291"], "Name": "Air Quality Sensor", "UUID": "0000008D-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000068-0000-1000-8000-0026BB765291", "0000008F-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000068-0000-1000-8000-0026BB765291", "0000008F-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291"], "Name": "Battery Service", "UUID": "00000096-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000114-0000-1000-8000-0026BB765291", "00000115-0000-1000-8000-0026BB765291", "00000116-0000-1000-8000-0026BB765291", "00000117-0000-1000-8000-0026BB765291", "00000120-0000-1000-8000-0026BB765291", "00000118-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000114-0000-1000-8000-0026BB765291", "00000115-0000-1000-8000-0026BB765291", "00000116-0000-1000-8000-0026BB765291", "00000117-0000-1000-8000-0026BB765291", "00000120-0000-1000-8000-0026BB765291", "00000118-0000-1000-8000-0026BB765291"], "Name": "Camera RTP Stream Management", "UUID": "00000110-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000092-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000093-0000-1000-8000-0026BB765291", "00000094-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000092-0000-1000-8000-0026BB765291"], "Name": "Carbon Dioxide Sensor", "UUID": "00000097-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000069-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000090-0000-1000-8000-0026BB765291", "00000091-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000069-0000-1000-8000-0026BB765291"], "Name": "Carbon Monoxide Sensor", "UUID": "0000007F-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000006A-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000006A-0000-1000-8000-0026BB765291"], "Name": "Contact Sensor", "UUID": "00000080-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["0000006F-0000-1000-8000-0026BB765291", "00000024-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291"], "Name": "Door", "UUID": "00000081-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000073-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000008-0000-1000-8000-0026BB765291", "00000119-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000073-0000-1000-8000-0026BB765291"], "Name": "Doorbell", "UUID": "00000121-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000028-0000-1000-8000-0026BB765291", "00000029-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "Name": "Fan", "UUID": "00000040-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000AF-0000-1000-8000-0026BB765291", "000000BF-0000-1000-8000-0026BB765291", "000000A7-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "00000028-0000-1000-8000-0026BB765291", "00000029-0000-1000-8000-0026BB765291", "000000B6-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291"], "Name": "Fan v2", "UUID": "000000B7-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000AC-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000AB-0000-1000-8000-0026BB765291", "000000AD-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000AC-0000-1000-8000-0026BB765291"], "Name": "Filter Maintenance", "UUID": "000000BA-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291"], "Name": "Faucet", "UUID": "000000D7-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000000E-0000-1000-8000-0026BB765291", "00000032-0000-1000-8000-0026BB765291", "00000024-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["0000001D-0000-1000-8000-0026BB765291", "0000001E-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000000E-0000-1000-8000-0026BB765291", "00000032-0000-1000-8000-0026BB765291", "00000024-0000-1000-8000-0026BB765291"], "Name": "Garage Door Opener", "UUID": "00000041-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000B1-0000-1000-8000-0026BB765291", "000000B2-0000-1000-8000-0026BB765291", "00000011-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000A7-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "000000B6-0000-1000-8000-0026BB765291", "0000000D-0000-1000-8000-0026BB765291", "00000012-0000-1000-8000-0026BB765291", "00000036-0000-1000-8000-0026BB765291", "00000029-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000B1-0000-1000-8000-0026BB765291", "000000B2-0000-1000-8000-0026BB765291", "00000011-0000-1000-8000-0026BB765291"], "Name": "Heater Cooler", "UUID": "000000BC-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000010-0000-1000-8000-0026BB765291", "000000B3-0000-1000-8000-0026BB765291", "000000B4-0000-1000-8000-0026BB765291", "000000B0-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000A7-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291", "000000B6-0000-1000-8000-0026BB765291", "000000B5-0000-1000-8000-0026BB765291", "000000C9-0000-1000-8000-0026BB765291", "000000CA-0000-1000-8000-0026BB765291", "00000029-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000010-0000-1000-8000-0026BB765291", "000000B3-0000-1000-8000-0026BB765291", "000000B4-0000-1000-8000-0026BB765291", "000000B0-0000-1000-8000-0026BB765291"], "Name": "Humidifier Dehumidifier", "UUID": "000000BD-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000010-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000010-0000-1000-8000-0026BB765291"], "Name": "Humidity Sensor", "UUID": "00000082-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000D1-0000-1000-8000-0026BB765291", "000000D2-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "000000D4-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000D1-0000-1000-8000-0026BB765291", "000000D2-0000-1000-8000-0026BB765291"], "Name": "Irrigation System", "UUID": "000000CF-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000070-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000070-0000-1000-8000-0026BB765291"], "Name": "Leak Sensor", "UUID": "00000083-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000006B-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000006B-0000-1000-8000-0026BB765291"], "Name": "Light Sensor", "UUID": "00000084-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000008-0000-1000-8000-0026BB765291", "00000013-0000-1000-8000-0026BB765291", "0000002F-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "Name": "Lightbulb", "UUID": "00000043-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000019-0000-1000-8000-0026BB765291", "00000037-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["0000001F-0000-1000-8000-0026BB765291", "00000005-0000-1000-8000-0026BB765291", "0000001A-0000-1000-8000-0026BB765291", "00000001-0000-1000-8000-0026BB765291", "0000001C-0000-1000-8000-0026BB765291", "0000000E-0000-1000-8000-0026BB765291", "00000022-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000019-0000-1000-8000-0026BB765291", "00000037-0000-1000-8000-0026BB765291"], "Name": "Lock Management", "UUID": "00000044-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000001D-0000-1000-8000-0026BB765291", "0000001E-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000001D-0000-1000-8000-0026BB765291", "0000001E-0000-1000-8000-0026BB765291"], "Name": "Lock Mechanism", "UUID": "00000045-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000119-0000-1000-8000-0026BB765291", "0000011A-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000119-0000-1000-8000-0026BB765291", "0000011A-0000-1000-8000-0026BB765291"], "Name": "Microphone", "UUID": "00000112-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000022-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000022-0000-1000-8000-0026BB765291"], "Name": "Motion Sensor", "UUID": "00000085-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000071-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000071-0000-1000-8000-0026BB765291"], "Name": "Occupancy Sensor", "UUID": "00000086-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291", "00000026-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291", "00000026-0000-1000-8000-0026BB765291"], "Name": "Outlet", "UUID": "00000047-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000066-0000-1000-8000-0026BB765291", "00000067-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "0000008E-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000066-0000-1000-8000-0026BB765291", "00000067-0000-1000-8000-0026BB765291"], "Name": "Security System", "UUID": "0000007E-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000CD-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000CD-0000-1000-8000-0026BB765291"], "Name": "Service Label", "UUID": "000000CC-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000C0-0000-1000-8000-0026BB765291", "000000AA-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "000000C1-0000-1000-8000-0026BB765291", "000000C2-0000-1000-8000-0026BB765291", "000000B6-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000C0-0000-1000-8000-0026BB765291", "000000AA-0000-1000-8000-0026BB765291"], "Name": "Slat", "UUID": "000000B9-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000076-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000076-0000-1000-8000-0026BB765291"], "Name": "Smoke Sensor", "UUID": "00000087-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000011A-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "00000119-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000011A-0000-1000-8000-0026BB765291"], "Name": "Speaker", "UUID": "00000113-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000073-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291", "000000CB-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000073-0000-1000-8000-0026BB765291"], "Name": "Stateless Programmable Switch", "UUID": "00000089-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000025-0000-1000-8000-0026BB765291"], "Name": "Switch", "UUID": "00000049-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["00000011-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000075-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "00000079-0000-1000-8000-0026BB765291", "0000007A-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["00000011-0000-1000-8000-0026BB765291"], "Name": "Temperature Sensor", "UUID": "0000008A-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000000F-0000-1000-8000-0026BB765291", "00000033-0000-1000-8000-0026BB765291", "00000011-0000-1000-8000-0026BB765291", "00000035-0000-1000-8000-0026BB765291", "00000036-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["00000010-0000-1000-8000-0026BB765291", "00000034-0000-1000-8000-0026BB765291", "0000000D-0000-1000-8000-0026BB765291", "00000012-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000000F-0000-1000-8000-0026BB765291", "00000033-0000-1000-8000-0026BB765291", "00000011-0000-1000-8000-0026BB765291", "00000035-0000-1000-8000-0026BB765291", "00000036-0000-1000-8000-0026BB765291"], "Name": "Thermostat", "UUID": "0000004A-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000D2-0000-1000-8000-0026BB765291", "000000D5-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["000000D3-0000-1000-8000-0026BB765291", "000000D4-0000-1000-8000-0026BB765291", "000000D6-0000-1000-8000-0026BB765291", "000000CB-0000-1000-8000-0026BB765291", "00000077-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["000000B0-0000-1000-8000-0026BB765291", "000000D2-0000-1000-8000-0026BB765291", "000000D5-0000-1000-8000-0026BB765291"], "Name": "Valve", "UUID": "000000D0-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["0000006F-0000-1000-8000-0026BB765291", "00000024-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291"], "Name": "Window", "UUID": "0000008B-0000-1000-8000-0026BB765291" }, { - "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291"], "OptionalCharacteristics": ["0000006F-0000-1000-8000-0026BB765291", "0000007B-0000-1000-8000-0026BB765291", "0000007D-0000-1000-8000-0026BB765291", "0000006C-0000-1000-8000-0026BB765291", "0000006E-0000-1000-8000-0026BB765291", "00000024-0000-1000-8000-0026BB765291", "00000023-0000-1000-8000-0026BB765291"], + "RequiredCharacteristics": ["0000006D-0000-1000-8000-0026BB765291", "0000007C-0000-1000-8000-0026BB765291", "00000072-0000-1000-8000-0026BB765291"], "Name": "Window Covering", "UUID": "0000008C-0000-1000-8000-0026BB765291" }] diff --git a/examples/bridged_accessories.rs b/examples/bridged_accessories.rs index 02ddaae..bd00536 100644 --- a/examples/bridged_accessories.rs +++ b/examples/bridged_accessories.rs @@ -1,11 +1,9 @@ -use std::{rc::Rc, cell::RefCell}; - -extern crate hap; +use std::sync::{Arc, Mutex}; use hap::{ - transport::{Transport, IpTransport}, - accessory::{Category, Information, bridge, outlet, door, security_system, valve}, + accessory::{bridge, door, outlet, security_system, valve, Category, Information}, characteristic::{Characteristic, Readable, Updatable}, + transport::{IpTransport, Transport}, Config, HapType, }; @@ -16,26 +14,30 @@ pub struct VirtualOutletInner { #[derive(Clone)] pub struct VirtualOutlet { - inner: Rc> + inner: Arc>, } impl VirtualOutlet { pub fn new(inner: VirtualOutletInner) -> VirtualOutlet { - VirtualOutlet { inner: Rc::new(RefCell::new(inner)) } + VirtualOutlet { + inner: Arc::new(Mutex::new(inner)), + } } } impl Readable for VirtualOutlet { fn on_read(&mut self, _: HapType) -> Option { println!("Outlet: On read."); - Some(self.inner.borrow().on) + Some(self.inner.lock().unwrap().on) } } impl Updatable for VirtualOutlet { fn on_update(&mut self, old_val: &bool, new_val: &bool, _: HapType) { println!("Outlet: On updated from {} to {}.", old_val, new_val); - if new_val != old_val { self.inner.borrow_mut().on = *new_val; } + if new_val != old_val { + self.inner.lock().unwrap().on = *new_val; + } } } @@ -46,13 +48,16 @@ pub struct VirtualDoorInner { #[derive(Clone)] pub struct VirtualDoor { - inner: Rc>, + inner: Arc>, current_position: Characteristic, } impl VirtualDoor { pub fn new(inner: VirtualDoorInner, current_position: Characteristic) -> VirtualDoor { - VirtualDoor { inner: Rc::new(RefCell::new(inner)), current_position } + VirtualDoor { + inner: Arc::new(Mutex::new(inner)), + current_position, + } } } @@ -61,11 +66,11 @@ impl Readable for VirtualDoor { match hap_type { HapType::CurrentPosition => { println!("Door: Current position read."); - Some(self.inner.borrow().current_position) + Some(self.inner.lock().unwrap().current_position) }, HapType::TargetPosition => { println!("Door: Target position read."); - Some(self.inner.borrow().target_position) + Some(self.inner.lock().unwrap().target_position) }, _ => None, } @@ -78,14 +83,14 @@ impl Updatable for VirtualDoor { HapType::CurrentPosition => { println!("Door: Current position updated from {} to {}.", old_val, new_val); if new_val != old_val { - self.inner.borrow_mut().current_position = *new_val; + self.inner.lock().unwrap().current_position = *new_val; } }, HapType::TargetPosition => { println!("Door: Target position updated from {} to {}.", old_val, new_val); if new_val != old_val { { - let mut inner = self.inner.borrow_mut(); + let mut inner = self.inner.lock().unwrap(); inner.target_position = *new_val; inner.current_position = *new_val; } @@ -101,38 +106,72 @@ fn main() { let bridge = bridge::new(Information { name: "Bridge".into(), ..Default::default() - }).unwrap(); + }) + .unwrap(); let mut outlet = outlet::new(Information { name: "Outlet".into(), ..Default::default() - }).unwrap(); + }) + .unwrap(); let virtual_outlet = VirtualOutlet::new(VirtualOutletInner { on: false }); - outlet.inner.outlet.inner.on.set_readable(virtual_outlet.clone()).unwrap(); + outlet + .inner + .outlet + .inner + .on + .set_readable(virtual_outlet.clone()) + .unwrap(); outlet.inner.outlet.inner.on.set_updatable(virtual_outlet).unwrap(); let mut door = door::new(Information { name: "Door".into(), ..Default::default() - }).unwrap(); + }) + .unwrap(); let virtual_door = VirtualDoor::new( - VirtualDoorInner { current_position: 0, target_position: 0 }, + VirtualDoorInner { + current_position: 0, + target_position: 0, + }, door.inner.door.inner.current_position.clone(), ); - door.inner.door.inner.current_position.set_readable(virtual_door.clone()).unwrap(); - door.inner.door.inner.current_position.set_updatable(virtual_door.clone()).unwrap(); - door.inner.door.inner.target_position.set_readable(virtual_door.clone()).unwrap(); - door.inner.door.inner.target_position.set_updatable(virtual_door).unwrap(); + door.inner + .door + .inner + .current_position + .set_readable(virtual_door.clone()) + .unwrap(); + door.inner + .door + .inner + .current_position + .set_updatable(virtual_door.clone()) + .unwrap(); + door.inner + .door + .inner + .target_position + .set_readable(virtual_door.clone()) + .unwrap(); + door.inner + .door + .inner + .target_position + .set_updatable(virtual_door) + .unwrap(); let security_system = security_system::new(Information { name: "Security System".into(), ..Default::default() - }).unwrap(); + }) + .unwrap(); let valve = valve::new(Information { name: "Valve".into(), ..Default::default() - }).unwrap(); + }) + .unwrap(); let config = Config { name: "Acme Bridge".into(), diff --git a/rustfmt.toml b/rustfmt.toml index ae72d81..c53259f 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,7 +1,16 @@ unstable_features = true -comment_width = 100 +edition = "2018" +version = "Two" + +comment_width = 120 +fn_single_line = true imports_layout = "HorizontalVertical" +max_width = 120 merge_imports = true match_block_trailing_comma = true +reorder_impl_items = true use_field_init_shorthand = true +use_try_shorthand = true +format_doc_comments = true match_arm_blocks = false +overflow_delimited_expr = true diff --git a/src/accessory/defined/bridge.rs b/src/accessory/defined/bridge.rs index 4f3fa78..864cc35 100644 --- a/src/accessory/defined/bridge.rs +++ b/src/accessory/defined/bridge.rs @@ -1,8 +1,10 @@ -use accessory::{HapAccessory, HapAccessoryService, Accessory, Information}; -use service::accessory_information::AccessoryInformation; -use event::EmitterPtr; +use crate::{ + accessory::{Accessory, HapAccessory, HapAccessoryService, Information}, + event::EmitterPtr, + service::accessory_information::AccessoryInformation, +}; -use Error; +use crate::Error; /// Bridge Accessory. pub type Bridge = Accessory; @@ -18,29 +20,15 @@ pub struct BridgeInner { } impl HapAccessory for BridgeInner { - fn get_id(&self) -> u64 { - self.id - } + fn get_id(&self) -> u64 { self.id } - fn set_id(&mut self, id: u64) { - self.id = id; - } + fn set_id(&mut self, id: u64) { self.id = id; } - fn get_services(&self) -> Vec<&HapAccessoryService> { - vec![ - &self.accessory_information, - ] - } + fn get_services(&self) -> Vec<&HapAccessoryService> { vec![&self.accessory_information] } - fn get_mut_services(&mut self) -> Vec<&mut HapAccessoryService> { - vec![ - &mut self.accessory_information, - ] - } + fn get_mut_services(&mut self) -> Vec<&mut HapAccessoryService> { vec![&mut self.accessory_information] } - fn get_mut_information(&mut self) -> &mut AccessoryInformation { - &mut self.accessory_information - } + fn get_mut_information(&mut self) -> &mut AccessoryInformation { &mut self.accessory_information } fn init_iids(&mut self, accessory_id: u64, event_emitter: EmitterPtr) -> Result<(), Error> { let mut next_iid = 1; diff --git a/src/accessory/defined/ip_camera.rs b/src/accessory/defined/ip_camera.rs index 9f7430e..5fbeb09 100644 --- a/src/accessory/defined/ip_camera.rs +++ b/src/accessory/defined/ip_camera.rs @@ -1,13 +1,10 @@ -use accessory::{HapAccessory, HapAccessoryService, Accessory, Information}; -use service::{ - HapService, - accessory_information::AccessoryInformation, - camera_rtp_stream_management, - microphone, +use crate::{ + accessory::{Accessory, HapAccessory, HapAccessoryService, Information}, + event::EmitterPtr, + service::{accessory_information::AccessoryInformation, camera_rtp_stream_management, microphone, HapService}, }; -use event::EmitterPtr; -use Error; +use crate::Error; /// IP Camera Accessory. pub type IpCamera = Accessory; @@ -27,13 +24,9 @@ pub struct IpCameraInner { } impl HapAccessory for IpCameraInner { - fn get_id(&self) -> u64 { - self.id - } + fn get_id(&self) -> u64 { self.id } - fn set_id(&mut self, id: u64) { - self.id = id; - } + fn set_id(&mut self, id: u64) { self.id = id; } fn get_services(&self) -> Vec<&HapAccessoryService> { vec![ @@ -51,9 +44,7 @@ impl HapAccessory for IpCameraInner { ] } - fn get_mut_information(&mut self) -> &mut AccessoryInformation { - &mut self.accessory_information - } + fn get_mut_information(&mut self) -> &mut AccessoryInformation { &mut self.accessory_information } fn init_iids(&mut self, accessory_id: u64, event_emitter: EmitterPtr) -> Result<(), Error> { let mut next_iid = 1; diff --git a/src/accessory/defined/lock.rs b/src/accessory/defined/lock.rs index d4963d5..6e30b95 100644 --- a/src/accessory/defined/lock.rs +++ b/src/accessory/defined/lock.rs @@ -1,13 +1,10 @@ -use accessory::{HapAccessory, HapAccessoryService, Accessory, Information}; -use service::{ - HapService, - accessory_information::AccessoryInformation, - lock_mechanism, - lock_management, +use crate::{ + accessory::{Accessory, HapAccessory, HapAccessoryService, Information}, + event::EmitterPtr, + service::{accessory_information::AccessoryInformation, lock_management, lock_mechanism, HapService}, }; -use event::EmitterPtr; -use Error; +use crate::Error; /// Lock Accessory. pub type Lock = Accessory; @@ -27,20 +24,12 @@ pub struct LockInner { } impl HapAccessory for LockInner { - fn get_id(&self) -> u64 { - self.id - } + fn get_id(&self) -> u64 { self.id } - fn set_id(&mut self, id: u64) { - self.id = id; - } + fn set_id(&mut self, id: u64) { self.id = id; } fn get_services(&self) -> Vec<&HapAccessoryService> { - vec![ - &self.accessory_information, - &self.lock_mechanism, - &self.lock_management, - ] + vec![&self.accessory_information, &self.lock_mechanism, &self.lock_management] } fn get_mut_services(&mut self) -> Vec<&mut HapAccessoryService> { @@ -51,9 +40,7 @@ impl HapAccessory for LockInner { ] } - fn get_mut_information(&mut self) -> &mut AccessoryInformation { - &mut self.accessory_information - } + fn get_mut_information(&mut self) -> &mut AccessoryInformation { &mut self.accessory_information } fn init_iids(&mut self, accessory_id: u64, event_emitter: EmitterPtr) -> Result<(), Error> { let mut next_iid = 1; diff --git a/src/accessory/defined/video_doorbell.rs b/src/accessory/defined/video_doorbell.rs index 3f9da84..caa0951 100644 --- a/src/accessory/defined/video_doorbell.rs +++ b/src/accessory/defined/video_doorbell.rs @@ -1,14 +1,16 @@ -use accessory::{HapAccessory, HapAccessoryService, Accessory, Information}; -use service::{ - HapService, - accessory_information::AccessoryInformation, - camera_rtp_stream_management, - speaker, - microphone, +use crate::{ + accessory::{Accessory, HapAccessory, HapAccessoryService, Information}, + event::EmitterPtr, + service::{ + accessory_information::AccessoryInformation, + camera_rtp_stream_management, + microphone, + speaker, + HapService, + }, }; -use event::EmitterPtr; -use Error; +use crate::Error; /// Video Doorbell Accessory. pub type VideoDoorbell = Accessory; @@ -30,13 +32,9 @@ pub struct VideoDoorbellInner { } impl HapAccessory for VideoDoorbellInner { - fn get_id(&self) -> u64 { - self.id - } + fn get_id(&self) -> u64 { self.id } - fn set_id(&mut self, id: u64) { - self.id = id; - } + fn set_id(&mut self, id: u64) { self.id = id; } fn get_services(&self) -> Vec<&HapAccessoryService> { vec![ @@ -56,9 +54,7 @@ impl HapAccessory for VideoDoorbellInner { ] } - fn get_mut_information(&mut self) -> &mut AccessoryInformation { - &mut self.accessory_information - } + fn get_mut_information(&mut self) -> &mut AccessoryInformation { &mut self.accessory_information } fn init_iids(&mut self, accessory_id: u64, event_emitter: EmitterPtr) -> Result<(), Error> { let mut next_iid = 1; diff --git a/src/accessory/mod.rs b/src/accessory/mod.rs index eeaf068..65a62b2 100644 --- a/src/accessory/mod.rs +++ b/src/accessory/mod.rs @@ -1,20 +1,25 @@ -use serde::ser::{Serialize, Serializer, SerializeStruct}; -use erased_serde; +use erased_serde::{self, __internal_serialize_trait_object, serialize_trait_object}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; -use service::{HapService, accessory_information::{self, AccessoryInformation}}; -use characteristic::{hardware_revision, accessory_flags}; -use event::EmitterPtr; +use crate::{ + characteristic::{accessory_flags, hardware_revision}, + event::EmitterPtr, + service::{ + accessory_information::{self, AccessoryInformation}, + HapService, + }, +}; -use Error; +use crate::Error; mod category; -pub use accessory::category::Category; +pub use crate::accessory::category::Category; mod defined; -pub use accessory::defined::*; +pub use crate::accessory::defined::*; mod includes; -pub use accessory::includes::*; +pub use crate::accessory::includes::*; /// `HapAccessoryService` is implemented by every `Service` inside of an `Accessory`. pub trait HapAccessoryService: HapService + erased_serde::Serialize {} @@ -51,9 +56,7 @@ pub struct Accessory { impl Accessory { /// Creates a new `Accessory`. - fn new(inner: T) -> Accessory { - Accessory { inner } - } + fn new(inner: T) -> Accessory { Accessory { inner } } } impl Serialize for Accessory { @@ -66,25 +69,15 @@ impl Serialize for Accessory { } impl HapAccessory for Accessory { - fn get_id(&self) -> u64 { - self.inner.get_id() - } + fn get_id(&self) -> u64 { self.inner.get_id() } - fn set_id(&mut self, id: u64) { - self.inner.set_id(id) - } + fn set_id(&mut self, id: u64) { self.inner.set_id(id) } - fn get_services(&self) -> Vec<&HapAccessoryService> { - self.inner.get_services() - } + fn get_services(&self) -> Vec<&HapAccessoryService> { self.inner.get_services() } - fn get_mut_services(&mut self) -> Vec<&mut HapAccessoryService> { - self.inner.get_mut_services() - } + fn get_mut_services(&mut self) -> Vec<&mut HapAccessoryService> { self.inner.get_mut_services() } - fn get_mut_information(&mut self) -> &mut AccessoryInformation { - self.inner.get_mut_information() - } + fn get_mut_information(&mut self) -> &mut AccessoryInformation { self.inner.get_mut_information() } fn init_iids(&mut self, accessory_id: u64, event_emitter: EmitterPtr) -> Result<(), Error> { self.inner.init_iids(accessory_id, event_emitter) @@ -97,7 +90,7 @@ impl HapAccessory for Accessory { /// # Examples /// /// ``` -/// use hap::accessory::{Information, outlet}; +/// use hap::accessory::{outlet, Information}; /// /// let info = Information { /// manufacturer: "Acme".into(), @@ -152,7 +145,7 @@ pub struct Information { pub hardware_revision: Option, /// When set indicates accessory requires additional setup. Use of Accessory Flags requires /// written approval by Apple in advance. - pub accessory_flags: Option, + pub accessory_flags: Option, } impl Information { diff --git a/src/characteristic/mod.rs b/src/characteristic/mod.rs index 30f524e..7b74fb0 100644 --- a/src/characteristic/mod.rs +++ b/src/characteristic/mod.rs @@ -1,16 +1,21 @@ -use std::{rc::Rc, cell::RefCell}; - -use serde::{ser::{Serialize, Serializer, SerializeStruct}, Deserialize}; -use serde_json; -use erased_serde; - -use HapType; -use event::{Event, EmitterPtr}; - -use Error; +use std::sync::{Arc, Mutex}; + +use erased_serde::{self, __internal_serialize_trait_object, serialize_trait_object}; +use serde::{ + ser::{Serialize, SerializeStruct, Serializer}, + Deserialize, +}; +use serde_derive::{Deserialize, Serialize}; +use serde_json::{self, json}; + +use crate::{ + event::{EmitterPtr, Event}, + Error, + HapType, +}; mod includes; -pub use characteristic::includes::*; +pub use crate::characteristic::includes::*; /// Inner type of a `Characteristic`. #[derive(Default)] @@ -34,8 +39,8 @@ pub struct Inner { valid_values: Option>, valid_values_range: Option<[T; 2]>, - readable: Option>>, - updatable: Option>>, + readable: Option + Send>>, + updatable: Option + Send>>, event_emitter: Option, } @@ -45,61 +50,71 @@ pub struct Inner { /// properties that determine how the value of the characteristic can be accessed #[derive(Clone, Default)] pub struct Characteristic { - pub inner: Rc>>, + pub inner: Arc>>, } -impl Characteristic where for<'de> T: Deserialize<'de> { +impl Characteristic +where + for<'de> T: Deserialize<'de>, +{ /// Creates a new `Characteristic`. pub fn new(inner: Inner) -> Characteristic { - Characteristic { inner: Rc::new(RefCell::new(inner)) } + Characteristic { + inner: Arc::new(Mutex::new(inner)), + } } /// Returns the ID of a Characteristic. - pub fn get_id(&self) -> Result { - Ok(self.inner.try_borrow()?.id) - } + pub fn get_id(&self) -> Result { Ok(self.inner.lock().expect("couldn't access characteristic").id) } /// Sets the ID of a Characteristic. pub fn set_id(&mut self, id: u64) -> Result<(), Error> { - self.inner.try_borrow_mut()?.id = id; + self.inner.lock().expect("couldn't access characteristic").id = id; Ok(()) } /// Sets the Accessory ID of a Characteristic. pub fn set_accessory_id(&mut self, accessory_id: u64) -> Result<(), Error> { - self.inner.try_borrow_mut()?.accessory_id = accessory_id; + self.inner.lock().expect("couldn't access characteristic").accessory_id = accessory_id; Ok(()) } /// Returns the `HapType` of a Characteristic. pub fn get_type(&self) -> Result { - Ok(self.inner.try_borrow()?.hap_type) + Ok(self.inner.lock().expect("couldn't access characteristic").hap_type) } /// Returns the `Format` of a Characteristic. pub fn get_format(&self) -> Result { - Ok(self.inner.try_borrow()?.format) + Ok(self.inner.lock().expect("couldn't access characteristic").format) } /// Returns the `Perm`s of a Characteristic. pub fn get_perms(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.perms.clone()) + Ok(self.inner.lock().expect("couldn't access characteristic").perms.clone()) } /// Sets the description of a Characteristic. pub fn set_description(&mut self, description: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.description = description; + self.inner.lock().expect("couldn't access characteristic").description = description; Ok(()) } /// Returns the event notifications value of a Characteristic. pub fn get_event_notifications(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.event_notifications) + Ok(self + .inner + .lock() + .expect("couldn't access characteristic") + .event_notifications) } /// Sets the event notifications value of a Characteristic. pub fn set_event_notifications(&mut self, event_notifications: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.event_notifications = event_notifications; + self.inner + .lock() + .expect("couldn't access characteristic") + .event_notifications = event_notifications; Ok(()) } @@ -107,7 +122,7 @@ impl Characteristic where for<'de> T: Deseria pub fn get_value(&mut self) -> Result { let mut val = None; { - let mut inner = self.inner.try_borrow_mut()?; + let mut inner = self.inner.lock().expect("couldn't access characteristic"); let hap_type = inner.hap_type; if let Some(ref mut readable) = inner.readable { val = readable.on_read(hap_type); @@ -117,7 +132,7 @@ impl Characteristic where for<'de> T: Deseria self.set_value(v)?; } - Ok(self.inner.try_borrow()?.value.clone()) + Ok(self.inner.lock().expect("couldn't access characteristic").value.clone()) } /// Sets the value of a Characteristic. @@ -125,17 +140,17 @@ impl Characteristic where for<'de> T: Deseria // TODO - check for min/max on types implementing PartialOrd // if let Some(ref max) = self.inner.try_borrow()?.max_value { // if &val > max { - // return Err(Error::new_io("value above max_value")); + // return Err(Error::from_str("value above max_value")); // } // } // if let Some(ref min) = self.inner.try_borrow()?.min_value { // if &val < min { - // return Err(Error::new_io("value below min_value")); + // return Err(Error::from_str("value below min_value")); // } // } { - let mut inner = self.inner.try_borrow_mut()?; + let mut inner = self.inner.lock().expect("couldn't access characteristic"); let old_val = inner.value.clone(); let hap_type = inner.hap_type; if let Some(ref mut updatable) = inner.updatable { @@ -144,81 +159,98 @@ impl Characteristic where for<'de> T: Deseria } { - let inner = self.inner.try_borrow()?; + let inner = self.inner.lock().expect("couldn't access characteristic"); if inner.event_notifications == Some(true) { if let Some(ref event_emitter) = inner.event_emitter { - event_emitter.try_borrow()?.emit(&Event::CharacteristicValueChanged { - aid: inner.accessory_id, - iid: inner.id, - value: json!(&val), - }); + event_emitter.lock().expect("couldn't access event_emitter").emit( + &Event::CharacteristicValueChanged { + aid: inner.accessory_id, + iid: inner.id, + value: json!(&val), + }, + ); } } } - self.inner.try_borrow_mut()?.value = val; + self.inner.lock().expect("couldn't access characteristic").value = val; Ok(()) } /// Returns the `Unit` of a Characteristic. pub fn get_unit(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.unit) + Ok(self.inner.lock().expect("couldn't access characteristic").unit) } /// Returns the maximum value of a Characteristic. pub fn get_max_value(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.max_value.clone()) + Ok(self + .inner + .lock() + .expect("couldn't access characteristic") + .max_value + .clone()) } /// Sets the maximum value of a Characteristic. pub fn set_max_value(&mut self, val: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.max_value = val; + self.inner.lock().expect("couldn't access characteristic").max_value = val; Ok(()) } /// Returns the minimum value of a Characteristic. pub fn get_min_value(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.min_value.clone()) + Ok(self + .inner + .lock() + .expect("couldn't access characteristic") + .min_value + .clone()) } /// Sets the minimum value of a Characteristic. pub fn set_min_value(&mut self, val: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.min_value = val; + self.inner.lock().expect("couldn't access characteristic").min_value = val; Ok(()) } /// Returns the step value of a Characteristic. pub fn get_step_value(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.step_value.clone()) + Ok(self + .inner + .lock() + .expect("couldn't access characteristic") + .step_value + .clone()) } /// Returns the step value of a Characteristic. pub fn set_step_value(&mut self, val: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.step_value = val; + self.inner.lock().expect("couldn't access characteristic").step_value = val; Ok(()) } /// Returns the maximum length of a Characteristic. pub fn get_max_len(&self) -> Result, Error> { - Ok(self.inner.try_borrow()?.max_len) + Ok(self.inner.lock().expect("couldn't access characteristic").max_len) } /// Sets a `Readable` on the Characteristic. - pub fn set_readable(&mut self, readable: impl Readable + 'static) -> Result<(), Error> { - self.inner.try_borrow_mut()?.readable = Some(Box::new(readable)); + pub fn set_readable(&mut self, readable: impl Readable + 'static + Send) -> Result<(), Error> { + self.inner.lock().expect("couldn't access characteristic").readable = Some(Box::new(readable)); Ok(()) } /// Sets an `Readable` on the Characteristic. - pub fn set_updatable(&mut self, updatable: impl Updatable + 'static) -> Result<(), Error> { - self.inner.try_borrow_mut()?.updatable = Some(Box::new(updatable)); + pub fn set_updatable(&mut self, updatable: impl Updatable + 'static + Send) -> Result<(), Error> { + self.inner.lock().expect("couldn't access characteristic").updatable = Some(Box::new(updatable)); Ok(()) } /// Sets a `hap::event::EmitterPtr` on the Characteristic. pub fn set_event_emitter(&mut self, event_emitter: Option) -> Result<(), Error> { - self.inner.try_borrow_mut()?.event_emitter = event_emitter; + self.inner.lock().expect("couldn't access characteristic").event_emitter = event_emitter; Ok(()) } } @@ -226,8 +258,7 @@ impl Characteristic where for<'de> T: Deseria impl Serialize for Characteristic { fn serialize(&self, serializer: S) -> Result { let mut state = serializer.serialize_struct("Characteristic", 15)?; - let inner = self.inner.try_borrow() - .expect("couldn't access Characteristic inner"); + let inner = self.inner.lock().expect("couldn't access characteristic"); state.serialize_field("iid", &inner.id)?; state.serialize_field("type", &inner.hap_type)?; state.serialize_field("format", &inner.format)?; @@ -308,55 +339,42 @@ pub trait HapCharacteristic: erased_serde::Serialize { serialize_trait_object!(HapCharacteristic); -impl HapCharacteristic for Characteristic where for<'de> T: Deserialize<'de> { - fn get_id(&self) -> Result { - self.get_id() - } +impl HapCharacteristic for Characteristic +where + for<'de> T: Deserialize<'de>, +{ + fn get_id(&self) -> Result { self.get_id() } - fn set_id(&mut self, id: u64) -> Result<(), Error> { - self.set_id(id) - } + fn set_id(&mut self, id: u64) -> Result<(), Error> { self.set_id(id) } - fn set_accessory_id(&mut self, accessory_id: u64) -> Result<(), Error> { - self.set_accessory_id(accessory_id) - } + fn set_accessory_id(&mut self, accessory_id: u64) -> Result<(), Error> { self.set_accessory_id(accessory_id) } - fn get_type(&self) -> Result { - self.get_type() - } + fn get_type(&self) -> Result { self.get_type() } - fn get_format(&self) -> Result { - self.get_format() - } + fn get_format(&self) -> Result { self.get_format() } - fn get_perms(&self) -> Result, Error> { - self.get_perms() - } + fn get_perms(&self) -> Result, Error> { self.get_perms() } - fn get_event_notifications(&self) -> Result, Error> { - self.get_event_notifications() - } + fn get_event_notifications(&self) -> Result, Error> { self.get_event_notifications() } fn set_event_notifications(&mut self, event_notifications: Option) -> Result<(), Error> { self.set_event_notifications(event_notifications) } - fn get_value(&mut self) -> Result { - Ok(json!(self.get_value()?)) - } + fn get_value(&mut self) -> Result { Ok(json!(self.get_value()?)) } fn set_value(&mut self, value: serde_json::Value) -> Result<(), Error> { let v; // the controller is setting boolean values // either as a boolean or as an integer - if self.inner.try_borrow()?.format == Format::Bool && value.is_number() { + if self.inner.lock().expect("couldn't access characteristic").format == Format::Bool && value.is_number() { let num_v: u8 = serde_json::from_value(value)?; if num_v == 0 { v = serde_json::from_value(json!(false))?; } else if num_v == 1 { v = serde_json::from_value(json!(true))?; } else { - return Err(Error::new_io("invalid value for bool characteristic")); + return Err(Error::from_str("invalid value for bool characteristic")); } } else { v = serde_json::from_value(value)?; @@ -364,9 +382,7 @@ impl HapCharacteristic for Characteristic whe self.set_value(v) } - fn get_unit(&self) -> Result, Error> { - self.get_unit() - } + fn get_unit(&self) -> Result, Error> { self.get_unit() } fn get_max_value(&self) -> Result, Error> { Ok(match self.get_max_value()? { @@ -389,9 +405,7 @@ impl HapCharacteristic for Characteristic whe }) } - fn get_max_len(&self) -> Result, Error> { - self.get_max_len() - } + fn get_max_len(&self) -> Result, Error> { self.get_max_len() } fn set_event_emitter(&mut self, event_emitter: Option) -> Result<(), Error> { self.set_event_emitter(event_emitter) @@ -473,7 +487,5 @@ pub enum Format { } impl Default for Format { - fn default() -> Format { - Format::String - } + fn default() -> Format { Format::String } } diff --git a/src/config.rs b/src/config.rs index 916b19d..ecc84f7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,32 +1,33 @@ use std::{ - net::IpAddr, - env::current_dir, - str, collections::hash_map::DefaultHasher, + env::current_dir, hash::{Hash, Hasher}, - rc::Rc, - cell::RefCell, + net::IpAddr, + str, + sync::{Arc, Mutex}, }; use eui48::MacAddress; -use rand::{self, Rng}; use pnet::datalink; +use rand::{self, Rng}; -use accessory::Category; -use db::Storage; -use transport::bonjour::{StatusFlag, FeatureFlag}; +use crate::{ + accessory::Category, + db::Storage, + transport::bonjour::{FeatureFlag, StatusFlag}, +}; -use Error; +use crate::Error; /// Reference counting pointer to a `Config`. -pub type ConfigPtr = Rc>; +pub type ConfigPtr = Arc>; /// The `Config` struct is used to store configuration options for the HomeKit Accessory Server. /// /// # Examples /// /// ``` -/// use hap::{Config, accessory::Category}; +/// use hap::{accessory::Category, Config}; /// /// let config = Config { /// storage_path: "/etc/homekit".into(), @@ -165,7 +166,8 @@ impl Default for Config { fn default() -> Config { let mut config = Config { storage_path: format!( - "{}/data", current_dir() + "{}/data", + current_dir() .expect("couldn't determine current directory") .to_str() .expect("couldn't stringify current directory") diff --git a/src/db/accessory_list.rs b/src/db/accessory_list.rs index 0ee52e1..682c7e4 100644 --- a/src/db/accessory_list.rs +++ b/src/db/accessory_list.rs @@ -1,25 +1,20 @@ -use std::{rc::Rc, cell::RefCell}; - -use serde::ser::{Serialize, Serializer, SerializeStruct}; -use erased_serde; - -use accessory::HapAccessory; -use characteristic::Perm; -use transport::http::{ - Status, - server::EventSubscriptions, - ReadResponseObject, - WriteObject, - WriteResponseObject, -}; -use event::EmitterPtr; +use std::sync::{Arc, Mutex}; + +use erased_serde::{self, __internal_serialize_trait_object, serialize_trait_object}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; -use Error; +use crate::{ + accessory::HapAccessory, + characteristic::Perm, + event::EmitterPtr, + transport::http::{server::EventSubscriptions, ReadResponseObject, Status, WriteObject, WriteResponseObject}, + Error, +}; /// `AccessoryList` is a wrapper type holding an `Rc` with a `Vec` of boxed Accessories. #[derive(Clone)] pub struct AccessoryList { - pub accessories: Rc>>, + pub accessories: Arc>>, event_emitter: EmitterPtr, id_count: u64, } @@ -27,38 +22,48 @@ pub struct AccessoryList { impl AccessoryList { /// Creates a new `AccessoryList`. pub fn new(event_emitter: EmitterPtr) -> AccessoryList { - AccessoryList { accessories: Rc::new(RefCell::new(Vec::new())), event_emitter, id_count: 1 } + AccessoryList { + accessories: Arc::new(Mutex::new(Vec::new())), + event_emitter, + id_count: 1, + } } /// Adds an Accessory to the `AccessoryList` and returns a pointer to the added Accessory. - pub fn add_accessory( - &mut self, - accessory: Box, - ) -> Result { + pub fn add_accessory(&mut self, accessory: Box) -> Result { let mut a = accessory; a.set_id(self.id_count); a.init_iids(self.id_count, self.event_emitter.clone())?; - let a_ptr = Rc::new(RefCell::new(a)); - self.accessories.try_borrow_mut()?.push(a_ptr.clone()); + let a_ptr = Arc::new(Mutex::new(a)); + self.accessories + .lock() + .expect("couldn't access accessories") + .push(a_ptr.clone()); self.id_count += 1; Ok(a_ptr) } /// Takes a pointer to an Accessory and removes the Accessory from the `AccessoryList`. pub fn remove_accessory(&mut self, accessory: &AccessoryListPtr) -> Result<(), Error> { - let accessory = accessory.try_borrow()?; + let accessory = accessory.lock().expect("couldn't access accessory"); let mut remove = None; - for (i, a) in self.accessories.try_borrow()?.iter().enumerate() { - if a.try_borrow()?.get_id() == accessory.get_id() { + for (i, a) in self + .accessories + .lock() + .expect("couldn't access accessories") + .iter() + .enumerate() + { + if a.lock().expect("couldn't access accessory").get_id() == accessory.get_id() { remove = Some(i); break; } } if let Some(i) = remove { - self.accessories.try_borrow_mut()?.remove(i); + self.accessories.lock().expect("couldn't access accessories").remove(i); return Ok(()); } - Err(Error::new_io("couldn't find the Accessory to remove")) + Err(Error::from_str("couldn't find the Accessory to remove")) } pub(crate) fn read_characteristic( @@ -86,9 +91,10 @@ impl AccessoryList { status: Some(0), }; - 'l: for accessory in self.accessories.try_borrow_mut()?.iter_mut() { - if accessory.try_borrow()?.get_id() == aid { - for service in accessory.try_borrow_mut()?.get_mut_services() { + 'l: for accessory in self.accessories.lock().expect("couldn't access accessories").iter_mut() { + let mut a = accessory.lock().expect("couldn't access accessory"); + if a.get_id() == aid { + for service in a.get_mut_services() { for characteristic in service.get_mut_characteristics() { if characteristic.get_id()? == iid { let characteristic_perms = characteristic.get_perms()?; @@ -135,10 +141,11 @@ impl AccessoryList { status: 0, }; - let mut a = self.accessories.try_borrow_mut()?; + let mut a = self.accessories.lock().expect("couldn't access accessories"); 'l: for accessory in a.iter_mut() { - if accessory.try_borrow()?.get_id() == write_object.aid { - for service in accessory.try_borrow_mut()?.get_mut_services() { + let mut a = accessory.lock().expect("couldn't access accessory"); + if a.get_id() == write_object.aid { + for service in a.get_mut_services() { for characteristic in service.get_mut_characteristics() { if characteristic.get_id()? == write_object.iid { let characteristic_perms = characteristic.get_perms()?; @@ -146,11 +153,16 @@ impl AccessoryList { if characteristic_perms.contains(&Perm::Events) { characteristic.set_event_notifications(Some(ev))?; let subscription = (write_object.aid, write_object.iid); - let mut es = event_subscriptions.try_borrow_mut()?; + let mut es = + event_subscriptions.lock().expect("couldn't access event_subscriptions"); let pos = es.iter().position(|&s| s == subscription); match (ev, pos) { - (true, None) => { es.push(subscription); }, - (false, Some(p)) => { es.remove(p); }, + (true, None) => { + es.push(subscription); + }, + (false, Some(p)) => { + es.remove(p); + }, _ => {}, } } else { @@ -190,4 +202,4 @@ impl AccessoryListMember for T {} serialize_trait_object!(AccessoryListMember); -pub type AccessoryListPtr = Rc>>; +pub type AccessoryListPtr = Arc>>; diff --git a/src/db/database.rs b/src/db/database.rs index ef60aed..c6c5936 100644 --- a/src/db/database.rs +++ b/src/db/database.rs @@ -1,25 +1,25 @@ -use std::{rc::Rc, cell::RefCell}; +use std::sync::{Arc, Mutex}; use uuid::Uuid; -use db::{file_storage, storage::Storage}; -use protocol::{Device, Pairing}; +use crate::{ + db::{file_storage, storage::Storage}, + protocol::{Device, Pairing}, +}; -use Error; +use crate::Error; /// Reference counting pointer to a `Database`. -pub type DatabasePtr = Rc>; +pub type DatabasePtr = Arc>; /// `Database` is a wrapper type around a boxed implementor of the `Storage` trait. pub struct Database { - storage: Box, + storage: Box, } impl Database { /// Creates a new `Database`. - pub fn new(storage: Box) -> Database { - Database { storage } - } + pub fn new(storage: Box) -> Database { Database { storage } } /// Creates a new `Database` with a `FileStorage` as its `Storage`. pub fn new_with_file_storage(dir: &str) -> Result { @@ -59,7 +59,7 @@ impl Database { /// Returns the stored `Pairing` for a given `Uuid`. pub fn get_pairing(&self, id: Uuid) -> Result { - let pairing_bytes = self.get_bytes(&id.simple().to_string())?; + let pairing_bytes = self.get_bytes(&id.to_simple().to_string())?; let pairing = Pairing::from_bytes(&pairing_bytes)?; Ok(pairing) } @@ -67,13 +67,13 @@ impl Database { /// Stores a given `Pairing`. pub fn set_pairing(&self, pairing: &Pairing) -> Result<(), Error> { let pairing_bytes = pairing.as_bytes()?; - self.set_bytes(&pairing.id.simple().to_string(), pairing_bytes)?; + self.set_bytes(&pairing.id.to_simple().to_string(), pairing_bytes)?; Ok(()) } /// Deletes the stored `Pairing` for a given `Uuid`. pub fn delete_pairing(&self, id: &Uuid) -> Result<(), Error> { - let mut key = id.simple().to_string(); + let mut key = id.to_simple().to_string(); key.push_str(".entity"); self.storage.delete(&key) } diff --git a/src/db/file_storage.rs b/src/db/file_storage.rs index 01b0c48..98c0b83 100644 --- a/src/db/file_storage.rs +++ b/src/db/file_storage.rs @@ -1,18 +1,18 @@ use std::{ - fs, - str, ffi::OsStr, - io::{Read, Write, BufReader, BufWriter}, + fs, + io::{BufReader, BufWriter, Read, Write}, os::unix::fs::PermissionsExt, path::{Path, PathBuf}, + str, }; -use byteorder::{ByteOrder, BigEndian, ReadBytesExt}; +use byteorder::{BigEndian, ByteOrder, ReadBytesExt}; use uuid::Uuid; -use db::storage::Storage; +use crate::db::storage::Storage; -use Error; +use crate::Error; /// `FileStorage` is an implementor of the `Storage` trait that stores data to the file system. pub struct FileStorage { @@ -28,25 +28,20 @@ impl FileStorage { let mut perms = fs::metadata(&path)?.permissions(); perms.set_mode(0o777); fs::set_permissions(&path, perms)?; - Ok(FileStorage {dir_path: path}) + Ok(FileStorage { dir_path: path }) } /// Returns a readable `File` for the given file name. fn file_for_read(&self, file: &str) -> Result { let file_path = self.path_to_file(file); - let file = fs::OpenOptions::new() - .read(true) - .open(file_path)?; + let file = fs::OpenOptions::new().read(true).open(file_path)?; Ok(file) } /// Returns a writable `File` for the given file name. fn file_for_write(&self, file: &str) -> Result { let file_path = self.path_to_file(file); - let file = fs::OpenOptions::new() - .write(true) - .create(true) - .open(file_path)?; + let file = fs::OpenOptions::new().write(true).create(true).open(file_path)?; Ok(file) } @@ -102,19 +97,17 @@ impl Storage for FileStorage { let mut buf = Vec::new(); reader.read_to_end(&mut buf)?; match str::from_utf8(&buf) { - Ok(uuid_str) => { - match Uuid::parse_str(uuid_str) { - Ok(value) => Ok(value), - _ => Err(Error::new_io("couldn't parse UUID")), - } + Ok(uuid_str) => match Uuid::parse_str(uuid_str) { + Ok(value) => Ok(value), + _ => Err(Error::from_str("couldn't parse UUID")), }, - _ => Err(Error::new_io("couldn't read UUID")), + _ => Err(Error::from_str("couldn't read UUID")), } } fn set_uuid(&self, key: &str, value: Uuid) -> Result<(), Error> { let mut writer = self.get_writer(key)?; - writer.write_all(value.hyphenated().to_string().as_bytes())?; + writer.write_all(value.to_hyphenated().to_string().as_bytes())?; Ok(()) } @@ -125,11 +118,12 @@ impl Storage for FileStorage { let entry = entry?; let path = entry.path(); if path.extension() == extension { - let key = path.file_stem() - .ok_or(Error::new_io("invalid file name"))? + let key = path + .file_stem() + .ok_or(Error::from_str("invalid file name"))? .to_os_string() .into_string() - .or(Err(Error::new_io("invalid file name")))?; + .or(Err(Error::from_str("invalid file name")))?; keys.push(key); } } diff --git a/src/db/mod.rs b/src/db/mod.rs index 42c13df..d37698a 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -3,7 +3,9 @@ mod database; mod file_storage; mod storage; -pub use self::accessory_list::{AccessoryList, AccessoryListMember, AccessoryListPtr}; -pub use self::database::{Database, DatabasePtr}; -pub use self::file_storage::FileStorage; -pub use self::storage::Storage; +pub use self::{ + accessory_list::{AccessoryList, AccessoryListMember, AccessoryListPtr}, + database::{Database, DatabasePtr}, + file_storage::FileStorage, + storage::Storage, +}; diff --git a/src/db/storage.rs b/src/db/storage.rs index 8e858ca..6b56571 100644 --- a/src/db/storage.rs +++ b/src/db/storage.rs @@ -1,8 +1,11 @@ -use std::{fs::File, io::{BufReader, BufWriter}}; +use std::{ + fs::File, + io::{BufReader, BufWriter}, +}; use uuid::Uuid; -use Error; +use crate::Error; /// `Storage` is implemented by the data storage methods HAP supports. Currently, that's just /// `FileStorage`. diff --git a/src/error.rs b/src/error.rs index 9921e44..9d3bd4b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,23 +1,24 @@ -use std::{cell, io, str, num, sync::mpsc}; +use std::{fmt, io, num, str, sync::mpsc}; -use serde_json; -use hyper; use chacha20_poly1305_aead; use eui48; +use failure::{self, err_msg, Context, Fail}; +use hyper::{self, http}; +use serde_json; -/// Error wrapper type. +/// ErrorKind wrapper type. #[derive(Debug, Fail)] -pub enum Error { +pub enum ErrorKind { #[fail(display = "IO Error {}", _0)] Io(#[cause] io::Error), #[fail(display = "JSON Error {}", _0)] Json(#[cause] serde_json::Error), #[fail(display = "HTTP Status Code {}", _0)] HttpStatus(hyper::StatusCode), - #[fail(display = "Borrow Error {}", _0)] - Borrow(#[cause] cell::BorrowError), - #[fail(display = "BorrowMut Error {}", _0)] - BorrowMut(#[cause] cell::BorrowMutError), + #[fail(display = "HTTP Error {}", _0)] + Http(#[cause] http::Error), + #[fail(display = "Hyper Error {}", _0)] + Hyper(#[cause] hyper::error::Error), #[fail(display = "ChaCha20-Poly1305-AEAD Error {}", _0)] ChaCha20Poly1305Aead(#[cause] chacha20_poly1305_aead::DecryptError), #[fail(display = "UTF-8 Error {}", _0)] @@ -28,71 +29,93 @@ pub enum Error { ParseInt(#[cause] num::ParseIntError), #[fail(display = "MPSC Send Error {}", _0)] MpscSend(#[cause] mpsc::SendError<()>), + #[fail(display = "Error {}", _0)] + Other(failure::Error), +} + +#[derive(Debug)] +pub struct Error { + kind: Context, } impl Error { - /// Creates a new `std::io::Error` wrapped in a `hap::Error::Io()`. - pub fn new_io(cause: &'static str) -> Error { - Error::Io(io::Error::new(io::ErrorKind::Other, cause.to_owned())) + /// Creates a new `Error` from a given `ErrorKind`. + pub fn new(kind: ErrorKind) -> Error { + Error { + kind: Context::new(kind), + } } + + /// Returns a reference to the `ErrorKind` of the `Error`. + pub fn kind(&self) -> &ErrorKind { &self.kind.get_context() } + + /// Creates a new `Error` from a `&'static str`. + pub fn from_str(cause: &'static str) -> Error { ErrorKind::Other(err_msg(cause)).into() } } -impl From for io::Error { - fn from(err: Error) -> io::Error { - io::Error::new(io::ErrorKind::Other, format!("{:?}", err)) +// impl Fail for Error { +// fn cause(&self) -> Option<&Fail> { self.kind.cause() } +// +// fn backtrace(&self) -> Option<&Backtrace> { self.kind.backtrace() } +// } + +impl std::error::Error for Error {} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.kind, f) } +} + +impl From for Error { + fn from(kind: ErrorKind) -> Error { + Error { + kind: Context::new(kind), + } } } +impl From for Error { + fn from(err: failure::Error) -> Error { ErrorKind::Other(err).into() } +} + impl From for Error { - fn from(err: io::Error) -> Error { - Error::Io(err) - } + fn from(err: io::Error) -> Error { ErrorKind::Io(err).into() } } +// TODO - fix it +// impl Into for Error { +// fn into(self) -> io::Error { +// io::Error::new(io::ErrorKind::Other, self.cause().into()) +// } +// } + impl From for Error { - fn from(err: serde_json::Error) -> Error { - Error::Json(err) - } + fn from(err: serde_json::Error) -> Error { ErrorKind::Json(err).into() } } -impl From for Error { - fn from(err: cell::BorrowError) -> Error { - Error::Borrow(err) - } +impl From for Error { + fn from(err: http::Error) -> Error { ErrorKind::Http(err).into() } } -impl From for Error { - fn from(err: cell::BorrowMutError) -> Error { - Error::BorrowMut(err) - } +impl From for Error { + fn from(err: hyper::error::Error) -> Error { ErrorKind::Hyper(err).into() } } impl From for Error { - fn from(err: chacha20_poly1305_aead::DecryptError) -> Error { - Error::ChaCha20Poly1305Aead(err) - } + fn from(err: chacha20_poly1305_aead::DecryptError) -> Error { ErrorKind::ChaCha20Poly1305Aead(err).into() } } impl From for Error { - fn from(err: str::Utf8Error) -> Error { - Error::Utf8(err) - } + fn from(err: str::Utf8Error) -> Error { ErrorKind::Utf8(err).into() } } impl From for Error { - fn from(err: eui48::ParseError) -> Error { - Error::MacAddressParse(err) - } + fn from(err: eui48::ParseError) -> Error { ErrorKind::MacAddressParse(err).into() } } impl From for Error { - fn from(err: num::ParseIntError) -> Error { - Error::ParseInt(err) - } + fn from(err: num::ParseIntError) -> Error { ErrorKind::ParseInt(err).into() } } impl From> for Error { - fn from(err: mpsc::SendError<()>) -> Error { - Error::MpscSend(err) - } + fn from(err: mpsc::SendError<()>) -> Error { ErrorKind::MpscSend(err).into() } } diff --git a/src/event.rs b/src/event.rs index 06d5a1e..c3e07e0 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1,26 +1,22 @@ -use std::{rc::Rc, cell::RefCell}; +use std::sync::{Arc, Mutex}; use serde_json::Value; pub enum Event { DevicePaired, DeviceUnpaired, - CharacteristicValueChanged { aid: u64, iid: u64, value: Value } + CharacteristicValueChanged { aid: u64, iid: u64, value: Value }, } #[derive(Default)] pub struct Emitter { - listeners: Vec>, + listeners: Vec>, } impl Emitter { - pub fn new() -> Emitter { - Emitter { listeners: vec![] } - } + pub fn new() -> Emitter { Emitter { listeners: vec![] } } - pub fn add_listener(&mut self, listener: Box) { - self.listeners.push(listener); - } + pub fn add_listener(&mut self, listener: Box) { self.listeners.push(listener); } pub fn emit(&self, event: &Event) { for listener in &self.listeners { @@ -30,4 +26,4 @@ impl Emitter { } /// Reference counting pointer to an `Emitter`. -pub type EmitterPtr = Rc>; +pub type EmitterPtr = Arc>; diff --git a/src/lib.rs b/src/lib.rs index 7ff8606..3fa851f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,51 +1,19 @@ -extern crate eui48; -extern crate libmdns; -extern crate uuid; -extern crate rand; -extern crate serde; -#[macro_use] -extern crate serde_json; -#[macro_use] -extern crate serde_derive; -extern crate bytes; -extern crate byteorder; -extern crate crypto; -#[macro_use] -extern crate futures; -extern crate hyper; -extern crate route_recognizer; -extern crate srp; -extern crate sha2; -extern crate pnet; -extern crate num; -extern crate ring; -extern crate chacha20_poly1305_aead; -#[macro_use] -extern crate tokio_core; -extern crate tokio_io; -#[macro_use] -extern crate erased_serde; -extern crate url; -#[macro_use] -extern crate failure; -#[macro_use] -extern crate log; - pub mod accessory; pub mod characteristic; pub mod service; pub mod db; -pub mod transport; pub mod protocol; - -mod pin; -mod event; +pub mod transport; mod config; mod error; +mod event; mod hap_type; +mod pin; -pub use config::Config; -pub use error::Error; -pub use hap_type::HapType; +pub use crate::{ + config::Config, + error::{Error, ErrorKind}, + hap_type::HapType, +}; diff --git a/src/pin.rs b/src/pin.rs index cca8458..de1a8ae 100644 --- a/src/pin.rs +++ b/src/pin.rs @@ -1,4 +1,4 @@ -use Error; +use crate::Error; pub type Pin = String; @@ -19,15 +19,15 @@ pub fn new(input: &str) -> Result { ]; for invalid_pin in &invalid_pins { if input == invalid_pin { - return Err(Error::new_io("invalid pin - too easy")); + return Err(Error::from_str("invalid pin - too easy")); } } if input.chars().count() != 8 { - return Err(Error::new_io("pin must be 8 characters long")); + return Err(Error::from_str("pin must be 8 characters long")); } for digit in input.chars() { if digit < '0' || digit > '9' { - return Err(Error::new_io("pin must only contain numbers")); + return Err(Error::from_str("pin must only contain numbers")); } } diff --git a/src/protocol/device.rs b/src/protocol/device.rs index ee31b3f..e977d6f 100644 --- a/src/protocol/device.rs +++ b/src/protocol/device.rs @@ -1,17 +1,19 @@ use std::{fmt, marker::PhantomData}; -use rand::{self, Rng}; use crypto::ed25519; +use rand::{self, Rng}; use serde::{ - ser::{Serialize, Serializer, SerializeTuple}, - de::{self, Deserialize, Deserializer, Visitor, SeqAccess}, + de::{self, Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeTuple, Serializer}, }; +use serde_derive::{Deserialize, Serialize}; use serde_json; -use db::{Database, DatabasePtr}; -use pin::Pin; - -use Error; +use crate::{ + db::{Database, DatabasePtr}, + pin::Pin, + Error, +}; /// `Device` represents instances of the HAP server. #[derive(Serialize, Deserialize)] @@ -26,13 +28,23 @@ pub struct Device { impl Device { /// Creates a new `Device` with a given key pair. pub fn new(id: String, pin: Pin, private_key: [u8; 64], public_key: [u8; 32]) -> Device { - Device {id, pin, public_key, private_key} + Device { + id, + pin, + public_key, + private_key, + } } /// Creates a new `Device` generating a random key pair. pub fn new_random(id: String, pin: Pin) -> Device { let (private_key, public_key) = generate_key_pair(); - Device {id, pin, private_key, public_key} + Device { + id, + pin, + private_key, + public_key, + } } /// Attempts to load a `Device` from a database and creates a new one with a random key pair if @@ -50,12 +62,12 @@ impl Device { /// Loads a `Device` from a database. pub fn load_from(database: &DatabasePtr) -> Result { - database.try_borrow()?.get_device() + database.lock().expect("couldn't access database").get_device() } /// Saves a `Device` to a database. pub fn save_to(&self, database: &DatabasePtr) -> Result<(), Error> { - database.try_borrow_mut()?.set_device(self)?; + database.lock().expect("couldn't access database").set_device(self)?; Ok(()) } @@ -81,9 +93,11 @@ fn generate_key_pair() -> ([u8; 64], [u8; 32]) { // see https://github.com/serde-rs/serde/issues/631 trait BigArray<'de>: Sized { fn serialize(&self, serializer: S) -> Result - where S: Serializer; + where + S: Serializer; fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de>; + where + D: Deserializer<'de>; } macro_rules! big_array { diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 31f0c1e..173f1c6 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -3,7 +3,9 @@ pub(crate) mod tlv; mod device; mod pairing; -pub use self::device::Device; -pub use self::pairing::{Pairing, Permissions}; +pub use self::{ + device::Device, + pairing::{Pairing, Permissions}, +}; pub(crate) use self::pairing::IdPtr; diff --git a/src/protocol/pairing.rs b/src/protocol/pairing.rs index 593889e..abfdcb6 100644 --- a/src/protocol/pairing.rs +++ b/src/protocol/pairing.rs @@ -1,11 +1,10 @@ -use std::{rc::Rc, cell::RefCell}; +use std::sync::{Arc, Mutex}; -use uuid::Uuid; +use serde_derive::{Deserialize, Serialize}; use serde_json; +use uuid::Uuid; -use db::DatabasePtr; - -use Error; +use crate::{db::DatabasePtr, Error}; /// `Pairing` represents paired controllers. #[derive(Debug, Serialize, Deserialize)] @@ -18,17 +17,21 @@ pub struct Pairing { impl Pairing { /// Creates a new `Pairing`. pub fn new(id: Uuid, permissions: Permissions, public_key: [u8; 32]) -> Pairing { - Pairing {id, permissions, public_key} + Pairing { + id, + permissions, + public_key, + } } /// Loads a `Pairing` from a database. pub fn load_from(id: Uuid, database: &DatabasePtr) -> Result { - database.try_borrow()?.get_pairing(id) + database.lock().expect("couldn't access database").get_pairing(id) } /// Saves a `Pairing` to a database. pub fn save_to(&self, database: &DatabasePtr) -> Result<(), Error> { - database.try_borrow_mut()?.set_pairing(self)?; + database.lock().expect("couldn't access database").set_pairing(self)?; Ok(()) } @@ -60,7 +63,7 @@ impl Permissions { match u { 0x00 => Ok(Permissions::User), 0x01 => Ok(Permissions::Admin), - _ => Err(Error::new_io("invalid permission Byte")) + _ => Err(Error::from_str("invalid permission Byte")), } } @@ -74,4 +77,4 @@ impl Permissions { } /// Reference counting pointer to a `Uuid`. -pub type IdPtr = Rc>>; +pub type IdPtr = Arc>>; diff --git a/src/protocol/tlv.rs b/src/protocol/tlv.rs index 40e3cad..c772237 100644 --- a/src/protocol/tlv.rs +++ b/src/protocol/tlv.rs @@ -1,13 +1,12 @@ -use std::{io, str, cell, collections::HashMap}; +use std::{cell, collections::HashMap, io, str}; use byteorder::{LittleEndian, WriteBytesExt}; -use srp::types::SrpAuthError; use chacha20_poly1305_aead; +use failure::Fail; +use srp::types::SrpAuthError; use uuid; -use protocol::pairing::Permissions; - -use error; +use crate::{error, protocol::pairing::Permissions}; /// Encodes a `HashMap>` in the format `` to a `Vec` of concatenated /// TLVs. @@ -41,7 +40,7 @@ pub fn encode(hm: HashMap>) -> Vec { } } } - }; + } vec } @@ -187,51 +186,35 @@ pub enum Error { } impl From for Error { - fn from(_: error::Error) -> Self { - Error::Unknown - } + fn from(_: error::Error) -> Self { Error::Unknown } } impl From for Error { - fn from(_: io::Error) -> Self { - Error::Unknown - } + fn from(_: io::Error) -> Self { Error::Unknown } } impl From for Error { - fn from(_: cell::BorrowError) -> Error { - Error::Unknown - } + fn from(_: cell::BorrowError) -> Error { Error::Unknown } } impl From for Error { - fn from(_: cell::BorrowMutError) -> Error { - Error::Unknown - } + fn from(_: cell::BorrowMutError) -> Error { Error::Unknown } } impl From for Error { - fn from(_: str::Utf8Error) -> Self { - Error::Unknown - } + fn from(_: str::Utf8Error) -> Self { Error::Unknown } } -impl From for Error { - fn from(_: uuid::ParseError) -> Self { - Error::Unknown - } +impl From for Error { + fn from(_: uuid::parser::ParseError) -> Self { Error::Unknown } } impl From for Error { - fn from(_: SrpAuthError) -> Self { - Error::Authentication - } + fn from(_: SrpAuthError) -> Self { Error::Authentication } } impl From for Error { - fn from(_: chacha20_poly1305_aead::DecryptError) -> Self { - Error::Authentication - } + fn from(_: chacha20_poly1305_aead::DecryptError) -> Self { Error::Authentication } } pub type Container = Vec; @@ -252,9 +235,7 @@ pub struct ErrorContainer { } impl ErrorContainer { - pub fn new(step: u8, error: Error) -> ErrorContainer { - ErrorContainer { step, error } - } + pub fn new(step: u8, error: Error) -> ErrorContainer { ErrorContainer { step, error } } } impl Encodable for ErrorContainer { diff --git a/src/service/mod.rs b/src/service/mod.rs index be7329b..534579f 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,10 +1,9 @@ -use serde::ser::{Serialize, Serializer, SerializeStruct}; +use serde::ser::{Serialize, SerializeStruct, Serializer}; -use characteristic::HapCharacteristic; -use HapType; +use crate::{characteristic::HapCharacteristic, HapType}; mod includes; -pub use service::includes::*; +pub use crate::service::includes::*; /// `HapService` is implemented by the inner type of every `Service`. pub trait HapService { @@ -36,9 +35,7 @@ pub struct Service { impl Service { /// Creates a new `Service`. - fn new(inner: T) -> Service { - Service { inner } - } + fn new(inner: T) -> Service { Service { inner } } } impl Serialize for Service { @@ -55,39 +52,21 @@ impl Serialize for Service { } impl HapService for Service { - fn get_id(&self) -> u64 { - self.inner.get_id() - } + fn get_id(&self) -> u64 { self.inner.get_id() } - fn set_id(&mut self, id: u64) { - self.inner.set_id(id) - } + fn set_id(&mut self, id: u64) { self.inner.set_id(id) } - fn get_type(&self) -> HapType { - self.inner.get_type() - } + fn get_type(&self) -> HapType { self.inner.get_type() } - fn get_hidden(&self) -> bool { - self.inner.get_hidden() - } + fn get_hidden(&self) -> bool { self.inner.get_hidden() } - fn set_hidden(&mut self, hidden: bool) { - self.inner.set_hidden(hidden) - } + fn set_hidden(&mut self, hidden: bool) { self.inner.set_hidden(hidden) } - fn get_primary(&self) -> bool { - self.inner.get_primary() - } + fn get_primary(&self) -> bool { self.inner.get_primary() } - fn set_primary(&mut self, primary: bool) { - self.inner.set_primary(primary) - } + fn set_primary(&mut self, primary: bool) { self.inner.set_primary(primary) } - fn get_characteristics(&self) -> Vec<&HapCharacteristic> { - self.inner.get_characteristics() - } + fn get_characteristics(&self) -> Vec<&HapCharacteristic> { self.inner.get_characteristics() } - fn get_mut_characteristics(&mut self) -> Vec<&mut HapCharacteristic> { - self.inner.get_mut_characteristics() - } + fn get_mut_characteristics(&mut self) -> Vec<&mut HapCharacteristic> { self.inner.get_mut_characteristics() } } diff --git a/src/transport/http/handler/accessories.rs b/src/transport/http/handler/accessories.rs new file mode 100644 index 0000000..cabb4c8 --- /dev/null +++ b/src/transport/http/handler/accessories.rs @@ -0,0 +1,34 @@ +use hyper::{Body, Response, StatusCode, Uri}; +use serde_json; + +use crate::{ + config::ConfigPtr, + db::{AccessoryList, DatabasePtr}, + event::EmitterPtr, + protocol::IdPtr, + transport::http::{handler::JsonHandler, json_response, server::EventSubscriptions}, + Error, +}; + +pub struct Accessories; + +impl Accessories { + pub fn new() -> Accessories { Accessories } +} + +impl JsonHandler for Accessories { + fn handle( + &mut self, + _: Uri, + _: Vec, + _: &IdPtr, + _: &EventSubscriptions, + _: &ConfigPtr, + _: &DatabasePtr, + accessories: &AccessoryList, + _: &EmitterPtr, + ) -> Result, Error> { + let resp_body = serde_json::to_vec(accessories)?; + json_response(resp_body, StatusCode::OK) + } +} diff --git a/src/transport/http/handlers/characteristics.rs b/src/transport/http/handler/characteristics.rs similarity index 74% rename from src/transport/http/handlers/characteristics.rs rename to src/transport/http/handler/characteristics.rs index d47ca06..e5fbedf 100644 --- a/src/transport/http/handlers/characteristics.rs +++ b/src/transport/http/handler/characteristics.rs @@ -1,33 +1,33 @@ use std::collections::HashMap; -use hyper::{Uri, StatusCode, server::Response}; +use hyper::{Body, Response, StatusCode, Uri}; use serde_json; use url::form_urlencoded; -use db::{AccessoryList, DatabasePtr}; -use config::ConfigPtr; -use transport::http::{ - Status, - CharacteristicResponseBody, - ReadResponseObject, - WriteObject, - WriteResponseObject, - server::EventSubscriptions, - handlers::JsonHandler, - json_response, - status_response, +use crate::{ + config::ConfigPtr, + db::{AccessoryList, DatabasePtr}, + event::EmitterPtr, + protocol::IdPtr, + transport::http::{ + handler::JsonHandler, + json_response, + server::EventSubscriptions, + status_response, + CharacteristicResponseBody, + ReadResponseObject, + Status, + WriteObject, + WriteResponseObject, + }, + Error, + ErrorKind, }; -use event::EmitterPtr; -use protocol::IdPtr; -use Error; - -pub struct GetCharacteristics {} +pub struct GetCharacteristics; impl GetCharacteristics { - pub fn new() -> GetCharacteristics { - GetCharacteristics {} - } + pub fn new() -> GetCharacteristics { GetCharacteristics } } impl JsonHandler for GetCharacteristics { @@ -41,10 +41,10 @@ impl JsonHandler for GetCharacteristics { _: &DatabasePtr, accessories: &AccessoryList, _: &EmitterPtr, - ) -> Result { + ) -> Result, Error> { if let Some(query) = uri.query() { let mut resp_body = CharacteristicResponseBody:: { - characteristics: Vec::new() + characteristics: Vec::new(), }; let mut some_err = false; @@ -54,24 +54,19 @@ impl JsonHandler for GetCharacteristics { queries.insert(key.into(), val.into()); } let (f_meta, f_perms, f_type, f_ev) = check_flags(&queries); - let q_id = queries.get("id").ok_or(Error::HttpStatus(StatusCode::BadRequest))?; + let q_id = queries + .get("id") + .ok_or(Error::new(ErrorKind::HttpStatus(StatusCode::BAD_REQUEST)))?; let ids = q_id.split(',').collect::>(); for id in ids { let id_pair = id.split('.').collect::>(); if id_pair.len() != 2 { - return Err(Error::HttpStatus(StatusCode::BadRequest)); + return Err(ErrorKind::HttpStatus(StatusCode::BAD_REQUEST).into()); } let aid = id_pair[0].parse::()?; let iid = id_pair[1].parse::()?; - let res_object = match accessories.read_characteristic( - aid, - iid, - f_meta, - f_perms, - f_type, - f_ev, - ) { + let res_object = match accessories.read_characteristic(aid, iid, f_meta, f_perms, f_type, f_ev) { Ok(mut res_object) => { if res_object.status != Some(0) { some_err = true; @@ -95,15 +90,16 @@ impl JsonHandler for GetCharacteristics { if some_err { let res = serde_json::to_vec(&resp_body)?; - return Ok(json_response(res, StatusCode::MultiStatus)); + return json_response(res, StatusCode::MULTI_STATUS); } for ref mut r in &mut resp_body.characteristics { r.status = None; } let res = serde_json::to_vec(&resp_body)?; - Ok(json_response(res, StatusCode::Ok)) + + json_response(res, StatusCode::OK) } else { - Ok(status_response(StatusCode::BadRequest)) + status_response(StatusCode::BAD_REQUEST) } } } @@ -121,9 +117,7 @@ fn check_flags(flags: &HashMap) -> (bool, bool, bool, bool) { pub struct UpdateCharacteristics {} impl UpdateCharacteristics { - pub fn new() -> UpdateCharacteristics { - UpdateCharacteristics {} - } + pub fn new() -> UpdateCharacteristics { UpdateCharacteristics {} } } impl JsonHandler for UpdateCharacteristics { @@ -137,10 +131,10 @@ impl JsonHandler for UpdateCharacteristics { _: &DatabasePtr, accessories: &AccessoryList, _: &EmitterPtr, - ) -> Result { + ) -> Result, Error> { let write_body: CharacteristicResponseBody = serde_json::from_slice(&body)?; let mut resp_body = CharacteristicResponseBody:: { - characteristics: Vec::new() + characteristics: Vec::new(), }; let mut some_err = false; let mut all_err = true; @@ -172,12 +166,12 @@ impl JsonHandler for UpdateCharacteristics { if all_err { let res = serde_json::to_vec(&resp_body)?; - Ok(json_response(res, StatusCode::BadRequest)) + json_response(res, StatusCode::BAD_REQUEST) } else if some_err { let res = serde_json::to_vec(&resp_body)?; - Ok(json_response(res, StatusCode::MultiStatus)) + json_response(res, StatusCode::MULTI_STATUS) } else { - Ok(status_response(StatusCode::NoContent)) + status_response(StatusCode::NO_CONTENT) } } } diff --git a/src/transport/http/handler/identify.rs b/src/transport/http/handler/identify.rs new file mode 100644 index 0000000..51bab8a --- /dev/null +++ b/src/transport/http/handler/identify.rs @@ -0,0 +1,53 @@ +use hyper::{Body, Response, StatusCode, Uri}; +use serde_json::{self, json}; + +use crate::{ + config::ConfigPtr, + db::{AccessoryList, DatabasePtr}, + event::EmitterPtr, + protocol::IdPtr, + transport::http::{handler::JsonHandler, json_response, server::EventSubscriptions, status_response, Status}, + Error, +}; + +pub struct Identify; + +impl Identify { + pub fn new() -> Identify { Identify } +} + +impl JsonHandler for Identify { + fn handle( + &mut self, + _: Uri, + _: Vec, + _: &IdPtr, + _: &EventSubscriptions, + _: &ConfigPtr, + database: &DatabasePtr, + accessory_list: &AccessoryList, + _: &EmitterPtr, + ) -> Result, Error> { + if database.lock().expect("couldn't access database").count_pairings()? > 0 { + let body = serde_json::to_vec(&json!({ "status": Status::InsufficientPrivileges as i32 }))?; + return json_response(body, StatusCode::BAD_REQUEST); + } + + for accessory in accessory_list + .accessories + .lock() + .expect("couldn't access accessory_list") + .iter_mut() + { + accessory + .lock() + .expect("couldn't access accessory") + .get_mut_information() + .inner + .identify + .set_value(true)?; + } + + status_response(StatusCode::NO_CONTENT) + } +} diff --git a/src/transport/http/handlers/mod.rs b/src/transport/http/handler/mod.rs similarity index 70% rename from src/transport/http/handlers/mod.rs rename to src/transport/http/handler/mod.rs index 962f34b..003687e 100644 --- a/src/transport/http/handlers/mod.rs +++ b/src/transport/http/handler/mod.rs @@ -1,13 +1,18 @@ -use hyper::{self, Uri, StatusCode, server::Response}; use futures::{future, Future}; +use hyper::{self, Body, Response, StatusCode, Uri}; -use config::ConfigPtr; -use db::{DatabasePtr, AccessoryList}; -use transport::http::{tlv_response, status_response, server::EventSubscriptions}; -use protocol::{tlv::{self, Encodable}, IdPtr}; -use event::EmitterPtr; - -use Error; +use crate::{ + config::ConfigPtr, + db::{AccessoryList, DatabasePtr}, + event::EmitterPtr, + protocol::{ + tlv::{self, Encodable}, + IdPtr, + }, + transport::http::{server::EventSubscriptions, status_response, tlv_response}, + Error, + ErrorKind, +}; pub mod accessories; pub mod characteristics; @@ -27,7 +32,7 @@ pub trait Handler { database: &DatabasePtr, accessories: &AccessoryList, event_emitter: &EmitterPtr, - ) -> Box>; + ) -> Box, Error = Error> + Send>; } pub trait TlvHandler { @@ -47,9 +52,7 @@ pub trait TlvHandler { pub struct TlvHandlerType(T); impl From for TlvHandlerType { - fn from(inst: T) -> TlvHandlerType { - TlvHandlerType(inst) - } + fn from(inst: T) -> TlvHandlerType { TlvHandlerType(inst) } } impl Handler for TlvHandlerType { @@ -63,15 +66,17 @@ impl Handler for TlvHandlerType { database: &DatabasePtr, _: &AccessoryList, event_emitter: &EmitterPtr, - ) -> Box> { + ) -> Box, Error = Error> + Send> { let response = match self.0.parse(body) { Err(e) => e.encode(), Ok(step) => match self.0.handle(step, controller_id, config, database, event_emitter) { Err(e) => e.encode(), Ok(res) => res.encode(), - } + }, }; - Box::new(future::ok(tlv_response(response, StatusCode::Ok))) + Box::new(future::result( + tlv_response(response, StatusCode::OK).map_err(Error::from), + )) } } @@ -86,15 +91,13 @@ pub trait JsonHandler { database: &DatabasePtr, accessory_list: &AccessoryList, event_emitter: &EmitterPtr, - ) -> Result; + ) -> Result, Error>; } pub struct JsonHandlerType(T); impl From for JsonHandlerType { - fn from(inst: T) -> JsonHandlerType { - JsonHandlerType(inst) - } + fn from(inst: T) -> JsonHandlerType { JsonHandlerType(inst) } } impl Handler for JsonHandlerType { @@ -108,7 +111,7 @@ impl Handler for JsonHandlerType { database: &DatabasePtr, accessory_list: &AccessoryList, event_emitter: &EmitterPtr, - ) -> Box> { + ) -> Box, Error = Error> + Send> { let response = match self.0.handle( uri, body, @@ -119,12 +122,12 @@ impl Handler for JsonHandlerType { accessory_list, event_emitter, ) { - Ok(res) => res, - Err(e) => match e { - Error::HttpStatus(status) => status_response(status), - _ => status_response(StatusCode::InternalServerError), + Ok(res) => Ok(res), + Err(e) => match e.kind() { + &ErrorKind::HttpStatus(status) => status_response(status), + _ => status_response(StatusCode::INTERNAL_SERVER_ERROR), }, }; - Box::new(future::ok(response)) + Box::new(future::result(response)) } } diff --git a/src/transport/http/handlers/pair_setup.rs b/src/transport/http/handler/pair_setup.rs similarity index 78% rename from src/transport/http/handlers/pair_setup.rs rename to src/transport/http/handler/pair_setup.rs index 29e0588..d286068 100644 --- a/src/transport/http/handlers/pair_setup.rs +++ b/src/transport/http/handler/pair_setup.rs @@ -1,24 +1,33 @@ -use std::{str, collections::HashMap, ops::BitXor}; +use std::{collections::HashMap, ops::BitXor, str}; -use rand::{self, Rng}; -use sha2::{Sha512, Digest}; +use chacha20_poly1305_aead; +use crypto::ed25519; +use log::debug; +use num::BigUint; +use rand::{self, distributions::Standard, Rng}; +use ring::{digest, hkdf, hmac}; +use sha2::{Digest, Sha512}; use srp::{ - server::{UserRecord, SrpServer}, - client::{SrpClient, srp_private_key}, + client::{srp_private_key, SrpClient}, groups::G_3072, + server::{SrpServer, UserRecord}, types::SrpGroup, }; -use num::BigUint; -use ring::{hkdf, hmac, digest}; -use chacha20_poly1305_aead; -use crypto::ed25519; use uuid::Uuid; -use db::DatabasePtr; -use config::ConfigPtr; -use transport::http::handlers::TlvHandler; -use protocol::{Device, Pairing, Permissions, tlv::{self, Type, Value}, IdPtr}; -use event::{Event, EmitterPtr}; +use crate::{ + config::ConfigPtr, + db::DatabasePtr, + event::{EmitterPtr, Event}, + protocol::{ + tlv::{self, Type, Value}, + Device, + IdPtr, + Pairing, + Permissions, + }, + transport::http::handler::TlvHandler, +}; struct Session { salt: Vec, @@ -35,7 +44,10 @@ pub struct PairSetup { impl PairSetup { pub fn new() -> PairSetup { - PairSetup { session: None, unsuccessful_tries: 0 } + PairSetup { + session: None, + unsuccessful_tries: 0, + } } } @@ -65,18 +77,26 @@ impl TlvHandler for PairSetup { Some(method) => match method[0] { x if x == StepNumber::StartReq as u8 => Ok(Step::Start), x if x == StepNumber::VerifyReq as u8 => { - let a_pub = decoded.get(&(Type::PublicKey as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::VerifyRes as u8, tlv::Error::Unknown) - )?; - let a_proof = decoded.get(&(Type::Proof as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::VerifyRes as u8, tlv::Error::Unknown) - )?; - Ok(Step::Verify { a_pub: a_pub.clone(), a_proof: a_proof.clone() }) + let a_pub = decoded.get(&(Type::PublicKey as u8)).ok_or(tlv::ErrorContainer::new( + StepNumber::VerifyRes as u8, + tlv::Error::Unknown, + ))?; + let a_proof = decoded.get(&(Type::Proof as u8)).ok_or(tlv::ErrorContainer::new( + StepNumber::VerifyRes as u8, + tlv::Error::Unknown, + ))?; + Ok(Step::Verify { + a_pub: a_pub.clone(), + a_proof: a_proof.clone(), + }) }, x if x == StepNumber::ExchangeReq as u8 => { - let data = decoded.get(&(Type::EncryptedData as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::ExchangeRes as u8, tlv::Error::Unknown) - )?; + let data = decoded + .get(&(Type::EncryptedData as u8)) + .ok_or(tlv::ErrorContainer::new( + StepNumber::ExchangeRes as u8, + tlv::Error::Unknown, + ))?; Ok(Step::Exchange { data: data.clone() }) }, _ => Err(tlv::ErrorContainer::new(StepNumber::Unknown as u8, tlv::Error::Unknown)), @@ -128,10 +148,7 @@ impl TlvHandler for PairSetup { } } -fn handle_start( - handler: &mut PairSetup, - database: &DatabasePtr, -) -> Result { +fn handle_start(handler: &mut PairSetup, database: &DatabasePtr) -> Result { debug!("/pair-setup - M1: Got SRP Start Request"); if handler.unsuccessful_tries > 99 { @@ -141,8 +158,8 @@ fn handle_start( let accessory = Device::load_from(database)?; let mut rng = rand::thread_rng(); - let salt = rng.gen_iter::().take(16).collect::>(); // s - let b = rng.gen_iter::().take(64).collect::>(); + let salt = rng.sample_iter::(&Standard).take(16).collect::>(); // s + let b = rng.sample_iter::(&Standard).take(64).collect::>(); let private_key = srp_private_key::(b"Pair-Setup", accessory.pin.as_bytes(), &salt); // x = H(s | H(I | ":" | P)) let srp_client = SrpClient::::new(&private_key, &G_3072); @@ -166,14 +183,14 @@ fn handle_start( debug!("/pair-setup - M2: Sending SRP Start Response"); - Ok(vec![Value::State(StepNumber::StartRes as u8), Value::PublicKey(b_pub), Value::Salt(salt.clone())]) + Ok(vec![ + Value::State(StepNumber::StartRes as u8), + Value::PublicKey(b_pub), + Value::Salt(salt.clone()), + ]) } -fn handle_verify( - handler: &mut PairSetup, - a_pub: &[u8], - a_proof: &[u8], -) -> Result { +fn handle_verify(handler: &mut PairSetup, a_pub: &[u8], a_proof: &[u8]) -> Result { debug!("/pair-setup - M3: Got SRP Verify Request"); if let Some(ref mut session) = handler.session { @@ -239,12 +256,7 @@ fn handle_exchange( let mut device_x = [0; 32]; let salt = hmac::SigningKey::new(&digest::SHA512, b"Pair-Setup-Controller-Sign-Salt"); - hkdf::extract_and_expand( - &salt, - &shared_secret, - b"Pair-Setup-Controller-Sign-Info", - &mut device_x, - ); + hkdf::extract_and_expand(&salt, &shared_secret, b"Pair-Setup-Controller-Sign-Info", &mut device_x); let mut device_info: Vec = Vec::new(); device_info.extend(&device_x); @@ -259,8 +271,8 @@ fn handle_exchange( let mut pairing_ltpk = [0; 32]; pairing_ltpk[..32].clone_from_slice(&device_ltpk[..32]); - if let Some(max_peers) = config.try_borrow()?.max_peers { - if database.try_borrow()?.count_pairings()? + 1 > max_peers { + if let Some(max_peers) = config.lock().expect("couldn't access config").max_peers { + if database.lock().expect("couldn't access database").count_pairings()? + 1 > max_peers { return Err(tlv::Error::MaxPeers); } } @@ -274,7 +286,7 @@ fn handle_exchange( &salt, &shared_secret, b"Pair-Setup-Accessory-Sign-Info", - &mut accessory_x + &mut accessory_x, ); let accessory = Device::load_from(database)?; @@ -293,20 +305,21 @@ fn handle_exchange( let mut encrypted_data = Vec::new(); let mut nonce = vec![0; 4]; nonce.extend(b"PS-Msg06"); - let auth_tag = chacha20_poly1305_aead::encrypt( - &encryption_key, - &nonce, - &[], - &encoded_sub_tlv, - &mut encrypted_data, - )?; + let auth_tag = + chacha20_poly1305_aead::encrypt(&encryption_key, &nonce, &[], &encoded_sub_tlv, &mut encrypted_data)?; encrypted_data.extend(&auth_tag); - event_emitter.try_borrow()?.emit(&Event::DevicePaired); + event_emitter + .lock() + .expect("couldn't access event_emitter") + .emit(&Event::DevicePaired); debug!("/pair-setup - M6: Sending SRP Exchange Response"); - Ok(vec![Value::State(StepNumber::ExchangeRes as u8), Value::EncryptedData(encrypted_data)]) + Ok(vec![ + Value::State(StepNumber::ExchangeRes as u8), + Value::EncryptedData(encrypted_data), + ]) } else { Err(tlv::Error::Unknown) } diff --git a/src/transport/http/handlers/pair_verify.rs b/src/transport/http/handler/pair_verify.rs similarity index 83% rename from src/transport/http/handlers/pair_verify.rs rename to src/transport/http/handler/pair_verify.rs index b618f47..e67e1e1 100644 --- a/src/transport/http/handlers/pair_verify.rs +++ b/src/transport/http/handler/pair_verify.rs @@ -1,17 +1,25 @@ -use std::{str, collections::HashMap}; +use std::{collections::HashMap, str}; -use rand::{self, Rng}; -use crypto::{curve25519, ed25519}; -use ring::{hkdf, hmac, digest}; use chacha20_poly1305_aead; -use uuid::Uuid; +use crypto::{curve25519, ed25519}; use futures::sync::oneshot; +use log::debug; +use rand::{self, Rng}; +use ring::{digest, hkdf, hmac}; +use uuid::Uuid; -use transport::{http::handlers::TlvHandler, tcp}; -use config::ConfigPtr; -use db::DatabasePtr; -use protocol::{Device, Pairing, tlv::{self, Type, Value}, IdPtr}; -use event::EmitterPtr; +use crate::{ + config::ConfigPtr, + db::DatabasePtr, + event::EmitterPtr, + protocol::{ + tlv::{self, Type, Value}, + Device, + IdPtr, + Pairing, + }, + transport::{http::handler::TlvHandler, tcp}, +}; struct Session { b_pub: [u8; 32], @@ -27,7 +35,10 @@ pub struct PairVerify { impl PairVerify { pub fn new(session_sender: oneshot::Sender) -> PairVerify { - PairVerify { session: None, session_sender: Some(session_sender) } + PairVerify { + session: None, + session_sender: Some(session_sender), + } } } @@ -53,15 +64,19 @@ impl TlvHandler for PairVerify { match decoded.get(&(Type::State as u8)) { Some(method) => match method[0] { x if x == StepNumber::StartReq as u8 => { - let a_pub = decoded.get(&(Type::PublicKey as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::StartRes as u8, tlv::Error::Unknown) - )?; + let a_pub = decoded.get(&(Type::PublicKey as u8)).ok_or(tlv::ErrorContainer::new( + StepNumber::StartRes as u8, + tlv::Error::Unknown, + ))?; Ok(Step::Start { a_pub: a_pub.clone() }) }, x if x == StepNumber::FinishReq as u8 => { - let data = decoded.get(&(Type::EncryptedData as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::FinishRes as u8, tlv::Error::Unknown) - )?; + let data = decoded + .get(&(Type::EncryptedData as u8)) + .ok_or(tlv::ErrorContainer::new( + StepNumber::FinishRes as u8, + tlv::Error::Unknown, + ))?; Ok(Step::Finish { data: data.clone() }) }, _ => Err(tlv::ErrorContainer::new(StepNumber::Unknown as u8, tlv::Error::Unknown)), @@ -131,12 +146,7 @@ fn handle_start( let mut encrypted_data = Vec::new(); let mut nonce = vec![0; 4]; nonce.extend(b"PV-Msg02"); - let auth_tag = chacha20_poly1305_aead::encrypt( - &session_key, - &nonce, &[], - &encoded_sub_tlv, - &mut encrypted_data, - )?; + let auth_tag = chacha20_poly1305_aead::encrypt(&session_key, &nonce, &[], &encoded_sub_tlv, &mut encrypted_data)?; encrypted_data.extend(&auth_tag); debug!("/pair-verify - M2: Sending Verify Start Response"); @@ -148,11 +158,7 @@ fn handle_start( ]) } -fn handle_finish( - handler: &mut PairVerify, - database: &DatabasePtr, - data: &[u8], -) -> Result { +fn handle_finish(handler: &mut PairVerify, database: &DatabasePtr, data: &[u8]) -> Result { debug!("/pair-verify - M3: Got Verify Finish Request"); if let Some(ref mut session) = handler.session { @@ -168,7 +174,7 @@ fn handle_finish( &[], &encrypted_data, &auth_tag, - &mut decrypted_data + &mut decrypted_data, )?; let sub_tlv = tlv::decode(decrypted_data); diff --git a/src/transport/http/handlers/pairings.rs b/src/transport/http/handler/pairings.rs similarity index 58% rename from src/transport/http/handlers/pairings.rs rename to src/transport/http/handler/pairings.rs index 8110dd4..3353dd1 100644 --- a/src/transport/http/handlers/pairings.rs +++ b/src/transport/http/handler/pairings.rs @@ -1,19 +1,25 @@ use std::str; +use log::debug; use uuid::Uuid; -use db::DatabasePtr; -use config::ConfigPtr; -use transport::http::handlers::TlvHandler; -use protocol::{Pairing, Permissions, tlv::{self, Type, Value}, IdPtr}; -use event::{Event, EmitterPtr}; - -pub struct Pairings {} +use crate::{ + config::ConfigPtr, + db::DatabasePtr, + event::{EmitterPtr, Event}, + protocol::{ + tlv::{self, Type, Value}, + IdPtr, + Pairing, + Permissions, + }, + transport::http::handler::TlvHandler, +}; + +pub struct Pairings; impl Pairings { - pub fn new() -> Pairings { - Pairings {} - } + pub fn new() -> Pairings { Pairings } } enum StepNumber { @@ -28,8 +34,14 @@ enum HandlerNumber { } pub enum HandlerType { - Add { pairing_id: Vec, ltpk: Vec, permissions: Permissions }, - Remove { pairing_id: Vec }, + Add { + pairing_id: Vec, + ltpk: Vec, + permissions: Permissions, + }, + Remove { + pairing_id: Vec, + }, List, } @@ -45,18 +57,17 @@ impl TlvHandler for Pairings { match decoded.get(&(Type::Method as u8)) { Some(handler) => match handler[0] { x if x == HandlerNumber::Add as u8 => { - let pairing_id = decoded.get(&(Type::Identifier as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown) - )?; - let ltpk = decoded.get(&(Type::PublicKey as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown) - )?; - let perms = decoded.get(&(Type::Permissions as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown) - )?; - let permissions = Permissions::from_u8(perms[0]).map_err( - |_| tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown) - )?; + let pairing_id = decoded + .get(&(Type::Identifier as u8)) + .ok_or(tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown))?; + let ltpk = decoded + .get(&(Type::PublicKey as u8)) + .ok_or(tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown))?; + let perms = decoded + .get(&(Type::Permissions as u8)) + .ok_or(tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown))?; + let permissions = Permissions::from_u8(perms[0]) + .map_err(|_| tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown))?; Ok(HandlerType::Add { pairing_id: pairing_id.clone(), ltpk: ltpk.clone(), @@ -64,15 +75,15 @@ impl TlvHandler for Pairings { }) }, x if x == HandlerNumber::Remove as u8 => { - let pairing_id = decoded.get(&(Type::Identifier as u8)).ok_or( - tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown) - )?; - Ok(HandlerType::Remove { pairing_id: pairing_id.clone() }) - }, - x if x == HandlerNumber::List as u8 => { - Ok(HandlerType::List) + let pairing_id = decoded + .get(&(Type::Identifier as u8)) + .ok_or(tlv::ErrorContainer::new(StepNumber::Res as u8, tlv::Error::Unknown))?; + Ok(HandlerType::Remove { + pairing_id: pairing_id.clone(), + }) }, - _ => Err(tlv::ErrorContainer::new(StepNumber::Unknown as u8, tlv::Error::Unknown)) + x if x == HandlerNumber::List as u8 => Ok(HandlerType::List), + _ => Err(tlv::ErrorContainer::new(StepNumber::Unknown as u8, tlv::Error::Unknown)), }, None => Err(tlv::ErrorContainer::new(StepNumber::Unknown as u8, tlv::Error::Unknown)), } @@ -87,7 +98,11 @@ impl TlvHandler for Pairings { event_emitter: &EmitterPtr, ) -> Result { match handler { - HandlerType::Add { pairing_id, ltpk, permissions } => match handle_add( + HandlerType::Add { + pairing_id, + ltpk, + permissions, + } => match handle_add( config, database, event_emitter, @@ -99,15 +114,11 @@ impl TlvHandler for Pairings { Ok(res) => Ok(res), Err(err) => Err(tlv::ErrorContainer::new(StepNumber::Res as u8, err)), }, - HandlerType::Remove { pairing_id } => match handle_remove( - database, - event_emitter, - controller_id, - &pairing_id, - ) { - Ok(res) => Ok(res), - Err(err) => Err(tlv::ErrorContainer::new(StepNumber::Res as u8, err)), - }, + HandlerType::Remove { pairing_id } => + match handle_remove(database, event_emitter, controller_id, &pairing_id) { + Ok(res) => Ok(res), + Err(err) => Err(tlv::ErrorContainer::new(StepNumber::Res as u8, err)), + }, HandlerType::List => match handle_list(database, controller_id) { Ok(res) => Ok(res), Err(err) => Err(tlv::ErrorContainer::new(StepNumber::Res as u8, err)), @@ -132,7 +143,7 @@ fn handle_add( let uuid_str = str::from_utf8(&pairing_id)?; let pairing_uuid = Uuid::parse_str(uuid_str)?; - let d = database.try_borrow_mut()?; + let d = database.lock().expect("couldn't access database"); match d.get_pairing(pairing_uuid) { Ok(mut pairing) => { if pairing.public_key != ltpk { @@ -142,10 +153,13 @@ fn handle_add( d.set_pairing(&pairing)?; drop(d); - event_emitter.try_borrow()?.emit(&Event::DevicePaired); + event_emitter + .lock() + .expect("couldn't access event_emitter") + .emit(&Event::DevicePaired); }, Err(_) => { - if let Some(max_peers) = config.try_borrow()?.max_peers { + if let Some(max_peers) = config.lock().expect("couldn't access config").max_peers { if d.count_pairings()? + 1 > max_peers { return Err(tlv::Error::MaxPeers); } @@ -153,11 +167,18 @@ fn handle_add( let mut public_key = [0; 32]; public_key.clone_from_slice(<pk); - let pairing = Pairing {id: pairing_uuid, permissions, public_key}; + let pairing = Pairing { + id: pairing_uuid, + permissions, + public_key, + }; d.set_pairing(&pairing)?; drop(d); - event_emitter.try_borrow()?.emit(&Event::DevicePaired); + event_emitter + .lock() + .expect("couldn't access event_emitter") + .emit(&Event::DevicePaired); }, } @@ -178,29 +199,29 @@ fn handle_remove( let uuid_str = str::from_utf8(&pairing_id)?; let pairing_uuid = Uuid::parse_str(uuid_str)?; - let d = database.try_borrow_mut()?; + let d = database.lock().expect("couldn't access database"); d.delete_pairing(&d.get_pairing(pairing_uuid)?.id)?; drop(d); - event_emitter.try_borrow()?.emit(&Event::DeviceUnpaired); + event_emitter + .lock() + .expect("couldn't access event_emitter") + .emit(&Event::DeviceUnpaired); debug!("/pairings - M2: Sending Remove Pairing Response"); Ok(vec![Value::State(StepNumber::Res as u8)]) } -fn handle_list( - database: &DatabasePtr, - controller_id: &IdPtr, -) -> Result { +fn handle_list(database: &DatabasePtr, controller_id: &IdPtr) -> Result { debug!("/pairings - M1: Got List Pairings Request"); check_admin(database, controller_id)?; - let pairings = database.try_borrow()?.list_pairings()?; + let pairings = database.lock().expect("couldn't access database").list_pairings()?; let mut list = vec![Value::State(StepNumber::Res as u8)]; for (i, pairing) in pairings.iter().enumerate() { - list.push(Value::Identifier(pairing.id.hyphenated().to_string())); + list.push(Value::Identifier(pairing.id.to_hyphenated().to_string())); list.push(Value::PublicKey(pairing.public_key.to_vec())); list.push(Value::Permissions(pairing.permissions.clone())); if i < pairings.len() { @@ -215,7 +236,12 @@ fn handle_list( fn check_admin(database: &DatabasePtr, controller_id: &IdPtr) -> Result<(), tlv::Error> { let err = tlv::Error::Authentication; - match database.try_borrow()?.get_pairing(controller_id.try_borrow()?.ok_or(err)?) { + match database.lock().expect("couldn't access database").get_pairing( + controller_id + .lock() + .expect("couldn't access controller_id") + .ok_or(err)?, + ) { Err(_) => Err(err), Ok(controller) => match controller.permissions { Permissions::Admin => Ok(()), diff --git a/src/transport/http/handlers/accessories.rs b/src/transport/http/handlers/accessories.rs deleted file mode 100644 index 012fe85..0000000 --- a/src/transport/http/handlers/accessories.rs +++ /dev/null @@ -1,35 +0,0 @@ -use hyper::{Uri, StatusCode, server::Response}; -use serde_json; - -use config::ConfigPtr; -use db::{AccessoryList, DatabasePtr}; -use transport::http::{server::EventSubscriptions, handlers::JsonHandler, json_response}; -use event::EmitterPtr; -use protocol::IdPtr; - -use Error; - -pub struct Accessories {} - -impl Accessories { - pub fn new() -> Accessories { - Accessories {} - } -} - -impl JsonHandler for Accessories { - fn handle( - &mut self, - _: Uri, - _: Vec, - _: &IdPtr, - _: &EventSubscriptions, - _: &ConfigPtr, - _: &DatabasePtr, - accessories: &AccessoryList, - _: &EmitterPtr, - ) -> Result { - let resp_body = serde_json::to_vec(accessories)?; - Ok(json_response(resp_body, StatusCode::Ok)) - } -} diff --git a/src/transport/http/handlers/identify.rs b/src/transport/http/handlers/identify.rs deleted file mode 100644 index 174532e..0000000 --- a/src/transport/http/handlers/identify.rs +++ /dev/null @@ -1,50 +0,0 @@ -use hyper::{Uri, StatusCode, server::Response}; -use serde_json; - -use config::ConfigPtr; -use db::{AccessoryList, DatabasePtr}; -use transport::http::{ - Status, - json_response, - status_response, - server::EventSubscriptions, - handlers::JsonHandler, -}; -use event::EmitterPtr; -use protocol::IdPtr; - -use Error; - -pub struct Identify {} - -impl Identify { - pub fn new() -> Identify { - Identify {} - } -} - -impl JsonHandler for Identify { - fn handle( - &mut self, - _: Uri, - _: Vec, - _: &IdPtr, - _: &EventSubscriptions, - _: &ConfigPtr, - database: &DatabasePtr, - accessory_list: &AccessoryList, - _: &EmitterPtr, - ) -> Result { - if database.try_borrow()?.count_pairings()? > 0 { - let body = serde_json::to_vec( - &json!({"status": Status::InsufficientPrivileges as i32}) - )?; - return Ok(json_response(body, StatusCode::BadRequest)); - } - - for accessory in accessory_list.accessories.try_borrow_mut()?.iter_mut() { - accessory.try_borrow_mut()?.get_mut_information().inner.identify.set_value(true)?; - } - Ok(status_response(StatusCode::NoContent)) - } -} diff --git a/src/transport/http/mod.rs b/src/transport/http/mod.rs index 252dbbf..6c39a68 100644 --- a/src/transport/http/mod.rs +++ b/src/transport/http/mod.rs @@ -1,11 +1,20 @@ -use hyper::{server::Response, header::{self, ContentLength}, StatusCode}; +use hyper::{ + header::{CONTENT_LENGTH, CONTENT_TYPE}, + Body, + Response, + StatusCode, +}; +use serde_derive::{Deserialize, Serialize}; use serde_json; -use characteristic::{Format, Perm, Unit}; -use HapType; +use crate::{ + characteristic::{Format, Perm, Unit}, + Error, + HapType, +}; +pub(crate) mod handler; pub(crate) mod server; -pub(crate) mod handlers; #[allow(dead_code)] pub enum Status { @@ -28,10 +37,10 @@ enum ContentType { } impl ContentType { - pub fn for_hyper(self) -> header::ContentType { + pub fn to_string(self) -> String { match self { - ContentType::PairingTLV8 => header::ContentType("application/pairing+tlv8".parse().unwrap()), - ContentType::HapJson => header::ContentType("application/hap+json".parse().unwrap()), + ContentType::PairingTLV8 => "application/pairing+tlv8".into(), + ContentType::HapJson => "application/hap+json".into(), } } } @@ -94,21 +103,24 @@ pub struct EventObject { pub value: serde_json::Value, } -pub fn tlv_response(body: Vec, status: StatusCode) -> Response { +pub fn tlv_response(body: Vec, status: StatusCode) -> Result, Error> { response(body, status, ContentType::PairingTLV8) } -pub fn json_response(body: Vec, status: StatusCode) -> Response { +pub fn json_response(body: Vec, status: StatusCode) -> Result, Error> { response(body, status, ContentType::HapJson) } -pub fn status_response(status: StatusCode) -> Response { - Response::new().with_status(status) +pub fn status_response(status: StatusCode) -> Result, Error> { + Response::builder() + .status(status) + .body(Body::empty()) + .map_err(Error::from) } -pub fn event_response(event_objects: Vec) -> Result, serde_json::Error> { +pub fn event_response(event_objects: Vec) -> Result, Error> { let body = serde_json::to_string(&CharacteristicResponseBody { - characteristics: event_objects + characteristics: event_objects, })?; let response = format!( "EVENT/1.0 200 OK\nContent-Type: application/hap+json\nContent-Length: {}\n\n{}", @@ -118,10 +130,11 @@ pub fn event_response(event_objects: Vec) -> Result, serde_ Ok(response.as_bytes().to_vec()) } -fn response(body: Vec, status: StatusCode, content_type: ContentType) -> Response { - Response::new() - .with_status(status) - .with_header(ContentLength(body.len() as u64)) - .with_header(content_type.for_hyper()) - .with_body(body) +fn response(body: Vec, status: StatusCode, content_type: ContentType) -> Result, Error> { + Response::builder() + .status(status) + .header(CONTENT_TYPE, content_type.to_string()) + .header(CONTENT_LENGTH, body.len() as u64) + .body(body.into()) + .map_err(Error::from) } diff --git a/src/transport/http/server.rs b/src/transport/http/server.rs index 90d2206..558831e 100644 --- a/src/transport/http/server.rs +++ b/src/transport/http/server.rs @@ -1,40 +1,37 @@ -use std::{net::SocketAddr, sync::Arc, rc::Rc, cell::RefCell}; +use std::{ + net::SocketAddr, + sync::{Arc, Mutex}, +}; -use hyper::{self, server::{Http, Request, Response, Service}, StatusCode, Method}; -use futures::{future, Future, stream::Stream, sync::oneshot}; +use futures::{future, stream::Stream, sync::oneshot, Future}; +use hyper::{self, server::conn::Http, service::Service, Body, Method, Request, Response, StatusCode}; +use log::error; use route_recognizer::Router; -use tokio_core::{net::TcpListener, reactor::Core}; - -use transport::{ - http::{ - EventObject, - status_response, - event_response, - handlers::{ - self, - pair_setup, - pair_verify, - accessories, - characteristics, - pairings, - identify +use tokio::net::TcpListener; + +use crate::{ + config::ConfigPtr, + db::{AccessoryList, DatabasePtr}, + event::{EmitterPtr, Event}, + protocol::IdPtr, + transport::{ + http::{ + event_response, + handler::{self, accessories, characteristics, identify, pair_setup, pair_verify, pairings}, + status_response, + EventObject, }, + tcp::{EncryptedStream, Session, StreamWrapper}, }, - tcp::{EncryptedStream, StreamWrapper, Session}, + Error, }; -use db::{AccessoryList, DatabasePtr}; -use config::ConfigPtr; -use event::{Event, EmitterPtr}; -use protocol::IdPtr; - -use Error; enum Route { - Get(Box>), - Post(Box>), + Get(Box>), + Post(Box>), GetPut { - _get: Box>, - _put: Box>, + _get: Box>, + _put: Box>, }, } @@ -59,39 +56,44 @@ impl Api { session_sender: oneshot::Sender, ) -> Api { let mut router = Router::new(); - router.add("/pair-setup", Route::Post( - Box::new(RefCell::new( - handlers::TlvHandlerType::from(pair_setup::PairSetup::new()) - )) - )); - router.add("/pair-verify", Route::Post( - Box::new(RefCell::new( - handlers::TlvHandlerType::from(pair_verify::PairVerify::new(session_sender)) - )) - )); - router.add("/accessories", Route::Get( - Box::new(RefCell::new( - handlers::JsonHandlerType::from(accessories::Accessories::new()) - )) - )); + router.add( + "/pair-setup", + Route::Post(Box::new(Mutex::new(handler::TlvHandlerType::from( + pair_setup::PairSetup::new(), + )))), + ); + router.add( + "/pair-verify", + Route::Post(Box::new(Mutex::new(handler::TlvHandlerType::from( + pair_verify::PairVerify::new(session_sender), + )))), + ); + router.add( + "/accessories", + Route::Get(Box::new(Mutex::new(handler::JsonHandlerType::from( + accessories::Accessories::new(), + )))), + ); router.add("/characteristics", Route::GetPut { - _get: Box::new(RefCell::new( - handlers::JsonHandlerType::from(characteristics::GetCharacteristics::new()) - )), - _put: Box::new(RefCell::new( - handlers::JsonHandlerType::from(characteristics::UpdateCharacteristics::new()) - )), + _get: Box::new(Mutex::new(handler::JsonHandlerType::from( + characteristics::GetCharacteristics::new(), + ))), + _put: Box::new(Mutex::new(handler::JsonHandlerType::from( + characteristics::UpdateCharacteristics::new(), + ))), }); - router.add("/pairings", Route::Post( - Box::new(RefCell::new( - handlers::TlvHandlerType::from(pairings::Pairings::new()) - )) - )); - router.add("/identify", Route::Post( - Box::new(RefCell::new( - handlers::JsonHandlerType::from(identify::Identify::new()) - )) - )); + router.add( + "/pairings", + Route::Post(Box::new(Mutex::new(handler::TlvHandlerType::from( + pairings::Pairings::new(), + )))), + ); + router.add( + "/identify", + Route::Post(Box::new(Mutex::new(handler::JsonHandlerType::from( + identify::Identify::new(), + )))), + ); Api { controller_id, @@ -106,13 +108,13 @@ impl Api { } impl Service for Api { - type Request = Request; - type Response = Response; - type Error = hyper::Error; - type Future = Box>; + type Error = Error; + type Future = Box, Error = Self::Error> + Send>; + type ReqBody = Body; + type ResBody = Body; - fn call(&self, req: Request) -> Self::Future { - let (method, uri, _, _, body) = req.deconstruct(); + fn call(&mut self, req: Request) -> Self::Future { + let (parts, body) = req.into_parts(); let router = self.router.clone(); let controller_id = self.controller_id.clone(); let event_subscriptions = self.event_subscriptions.clone(); @@ -121,16 +123,18 @@ impl Service for Api { let accessories = self.accessories.clone(); let event_emitter = self.event_emitter.clone(); - Box::new(body.fold(vec![], |mut v, c| { - v.extend(c.to_vec()); - future::ok::, hyper::Error>(v) - }).and_then(move |body| { - if let Ok(route_match) = router.recognize(uri.path()) { - match (route_match.handler, method) { - (&Route::Get(ref handler), Method::Get) => handler.borrow_mut() - .handle( - uri, - body, + Box::new( + body.fold(vec![], |mut v, c| { + v.extend(c.to_vec()); + future::ok::, hyper::Error>(v) + }) + .map_err(|e| e.into()) + .and_then(move |body| { + if let Ok(route_match) = router.recognize(parts.uri.path()) { + match (route_match.handler, parts.method) { + (&Route::Get(ref handler), Method::GET) => handler.lock().unwrap().handle( + parts.uri, + body.into(), &controller_id, &event_subscriptions, &config, @@ -138,10 +142,9 @@ impl Service for Api { &accessories, &event_emitter, ), - (&Route::Post(ref handler), Method::Post) => handler.borrow_mut() - .handle( - uri, - body, + (&Route::Post(ref handler), Method::POST) => handler.lock().unwrap().handle( + parts.uri, + body.into(), &controller_id, &event_subscriptions, &config, @@ -149,10 +152,9 @@ impl Service for Api { &accessories, &event_emitter, ), - (&Route::GetPut { ref _get, ref _put }, Method::Get) => _get.borrow_mut() - .handle( - uri, - body, + (&Route::GetPut { ref _get, ref _put }, Method::GET) => _get.lock().unwrap().handle( + parts.uri, + body.into(), &controller_id, &event_subscriptions, &config, @@ -160,10 +162,9 @@ impl Service for Api { &accessories, &event_emitter, ), - (&Route::GetPut { ref _get, ref _put }, Method::Put) => _put.borrow_mut() - .handle( - uri, - body, + (&Route::GetPut { ref _get, ref _put }, Method::PUT) => _put.lock().unwrap().handle( + parts.uri, + body.into(), &controller_id, &event_subscriptions, &config, @@ -171,16 +172,17 @@ impl Service for Api { &accessories, &event_emitter, ), - _ => Box::new(future::ok(status_response(StatusCode::BadRequest))), + _ => Box::new(future::result(status_response(StatusCode::BAD_REQUEST))), + } + } else { + Box::new(future::result(status_response(StatusCode::NOT_FOUND))) } - } else { - Box::new(future::ok(status_response(StatusCode::NotFound))) - } - })) + }), + ) } } -pub type EventSubscriptions = Rc>>; +pub type EventSubscriptions = Arc>>; pub fn serve( socket_addr: &SocketAddr, @@ -189,58 +191,72 @@ pub fn serve( accessories: &AccessoryList, event_emitter: &EmitterPtr, ) -> Result<(), Error> { - let mut evt_loop = Core::new()?; - let listener = TcpListener::bind(socket_addr, &evt_loop.handle())?; - let http: Http = Http::new(); - let handle = evt_loop.handle(); - - let server = listener.incoming().for_each(|(stream, _)| { - let (encrypted_stream, stream_incoming, stream_outgoing, session_sender) = EncryptedStream::new(stream); - let stream_wrapper = StreamWrapper::new(stream_incoming, stream_outgoing.clone()); - let event_subscriptions = Rc::new(RefCell::new(vec![])); - let api = Api::new( - encrypted_stream.controller_id.clone(), - event_subscriptions.clone(), - config.clone(), - database.clone(), - accessories.clone(), - event_emitter.clone(), - session_sender, - ); + let listener = TcpListener::bind(socket_addr)?; + + let config = config.clone(); + let database = database.clone(); + let accessories = accessories.clone(); + let event_emitter = event_emitter.clone(); - event_emitter.try_borrow_mut() - .expect("couldn't add listener for characteristic value change events") - .add_listener(Box::new(move |event| { - match *event { - Event::CharacteristicValueChanged { aid, iid, ref value } => { - let mut dropped_subscriptions = vec![]; - for (i, &(s_aid, s_iid)) in event_subscriptions.try_borrow() - .expect("couldn't read event subscriptions") - .iter().enumerate() { - if s_aid == aid && s_iid == iid { - let event = EventObject { aid, iid, value: value.clone() }; - let event_res = event_response(vec![event]) - .expect("couldn't create event response"); - if stream_outgoing.unbounded_send(event_res).is_err() { - dropped_subscriptions.push(i); + let server = listener + .incoming() + .for_each(move |stream| { + let (encrypted_stream, stream_incoming, stream_outgoing, session_sender) = EncryptedStream::new(stream); + let stream_wrapper = StreamWrapper::new(stream_incoming, stream_outgoing.clone()); + let event_subscriptions = Arc::new(Mutex::new(vec![])); + let api = Api::new( + encrypted_stream.controller_id.clone(), + event_subscriptions.clone(), + config.clone(), + database.clone(), + accessories.clone(), + event_emitter.clone(), + session_sender, + ); + let http = Http::new(); + + event_emitter + .lock() + .expect("couldn't add listener for characteristic value change events") + .add_listener(Box::new(move |event| match *event { + Event::CharacteristicValueChanged { aid, iid, ref value } => { + let mut dropped_subscriptions = vec![]; + for (i, &(s_aid, s_iid)) in event_subscriptions + .lock() + .expect("couldn't read event subscriptions") + .iter() + .enumerate() + { + if s_aid == aid && s_iid == iid { + let event = EventObject { + aid, + iid, + value: value.clone(), + }; + let event_res = event_response(vec![event]).expect("couldn't create event response"); + if stream_outgoing.unbounded_send(event_res).is_err() { + dropped_subscriptions.push(i); + } } } - } - let mut ev = event_subscriptions.try_borrow_mut() - .expect("couldn't modify event subscriptions"); - for s in dropped_subscriptions { - ev.remove(s); - } - }, - _ => {}, - } - })); + let mut ev = event_subscriptions.lock().expect("couldn't modify event subscriptions"); + for s in dropped_subscriptions { + ev.remove(s); + } + }, + _ => {}, + })); - handle.spawn(encrypted_stream.map_err(|_| ()).map(|_| ())); - handle.spawn(http.serve_connection(stream_wrapper, api).map_err(|_| ()).map(|_| ())); - Ok(()) - }); + tokio::spawn(encrypted_stream.map(|_| ()).map_err(|e| error!("{}", e))); + tokio::spawn( + http.serve_connection(stream_wrapper, api) + .map(|_| ()) + .map_err(|e| error!("{}", e)), + ); + Ok(()) + }) + .map_err(|e| error!("{}", e)); - evt_loop.run(server)?; + tokio::run(server); Ok(()) } diff --git a/src/transport/ip.rs b/src/transport/ip.rs index 6d787ae..3b371a7 100644 --- a/src/transport/ip.rs +++ b/src/transport/ip.rs @@ -1,21 +1,23 @@ -use std::{rc::Rc, cell::RefCell, net::SocketAddr}; +use std::{ + net::SocketAddr, + sync::{Arc, Mutex}, +}; -use config::{Config, ConfigPtr}; -use db::{ - Storage, - Database, - DatabasePtr, - FileStorage, - AccessoryList, - AccessoryListMember, - AccessoryListPtr, +use crate::{ + config::{Config, ConfigPtr}, + db::{AccessoryList, AccessoryListMember, AccessoryListPtr, Database, DatabasePtr, FileStorage, Storage}, + event::{Emitter, EmitterPtr, Event}, + pin, + protocol::Device, + transport::{ + bonjour::StatusFlag, + http, + mdns::{Responder, ResponderPtr}, + Transport, + }, }; -use pin; -use protocol::Device; -use transport::{http, mdns::{Responder, ResponderPtr}, bonjour::StatusFlag, Transport}; -use event::{Event, Emitter, EmitterPtr}; -use Error; +use crate::Error; /// Transport via TCP/IP. pub struct IpTransport { @@ -34,9 +36,9 @@ impl IpTransport { /// /// ``` /// use hap::{ + /// accessory::{bridge, lightbulb, Category, Information}, + /// transport::{IpTransport, Transport}, /// Config, - /// accessory::{Category, Information, bridge, lightbulb}, - /// transport::{Transport, IpTransport}, /// }; /// /// let config = Config { @@ -80,13 +82,17 @@ impl IpTransport { let pin = pin::new(&config.pin)?; let device = Device::load_or_new(config.device_id.to_hex_string(), pin, &database)?; - let event_emitter = Rc::new(RefCell::new(Emitter::new())); - let mdns_responder = Rc::new(RefCell::new(Responder::new(&config.name, config.port, config.txt_records()))); + let event_emitter = Arc::new(Mutex::new(Emitter::new())); + let mdns_responder = Arc::new(Mutex::new(Responder::new( + &config.name, + config.port, + config.txt_records(), + ))); let ip_transport = IpTransport { - config: Rc::new(RefCell::new(config)), + config: Arc::new(Mutex::new(config)), storage, - database: Rc::new(RefCell::new(database)), + database: Arc::new(Mutex::new(database)), accessories: AccessoryList::new(event_emitter.clone()), event_emitter, mdns_responder, @@ -99,27 +105,30 @@ impl IpTransport { impl Transport for IpTransport { fn start(&mut self) -> Result<(), Error> { - self.mdns_responder.try_borrow_mut()?.start(); + self.mdns_responder + .lock() + .expect("couldn't access event_emitter") + .start(); let (ip, port) = { - let c = self.config.try_borrow()?; + let c = self.config.lock().expect("couldn't access config"); (c.ip, c.port) }; let config = self.config.clone(); let database = self.database.clone(); let mdns_responder = self.mdns_responder.clone(); - self.event_emitter.try_borrow_mut()?.add_listener(Box::new(move |event| { - match *event { + self.event_emitter + .lock() + .expect("couldn't access event_emitter") + .add_listener(Box::new(move |event| match *event { Event::DevicePaired => { - if let Ok(count) = database.try_borrow() - .expect("couldn't access database") - .count_pairings() { + if let Ok(count) = database.lock().expect("couldn't access database").count_pairings() { if count > 0 { - let mut c = config.try_borrow_mut() - .expect("couldn't access config"); + let mut c = config.lock().expect("couldn't access config"); c.status_flag = StatusFlag::Zero; - mdns_responder.try_borrow_mut() + mdns_responder + .lock() .expect("couldn't access mDNS responder") .update_txt_records(c.txt_records()) .expect("couldn't update mDNS TXT records"); @@ -127,14 +136,12 @@ impl Transport for IpTransport { } }, Event::DeviceUnpaired => { - if let Ok(count) = database.try_borrow() - .expect("couldn't access database") - .count_pairings() { + if let Ok(count) = database.lock().expect("couldn't access database").count_pairings() { if count == 0 { - let mut c = config.try_borrow_mut() - .expect("couldn't access config"); + let mut c = config.lock().expect("couldn't access config"); c.status_flag = StatusFlag::NotPaired; - mdns_responder.try_borrow_mut() + mdns_responder + .lock() .expect("couldn't access mDNS responder") .update_txt_records(c.txt_records()) .expect("couldn't update mDNS TXT records"); @@ -142,8 +149,7 @@ impl Transport for IpTransport { } }, _ => {}, - } - })); + })); http::server::serve( &SocketAddr::new(ip, port), @@ -156,11 +162,17 @@ impl Transport for IpTransport { } fn stop(&self) -> Result<(), Error> { - self.mdns_responder.try_borrow()?.stop()?; + self.mdns_responder + .lock() + .expect("couldn't access mDNS responder") + .stop()?; Ok(()) } - fn add_accessory(&mut self, accessory: A) -> Result { + fn add_accessory( + &mut self, + accessory: A, + ) -> Result { self.accessories.add_accessory(Box::new(accessory)) } diff --git a/src/transport/mdns.rs b/src/transport/mdns.rs index 1a4255a..73499a3 100644 --- a/src/transport/mdns.rs +++ b/src/transport/mdns.rs @@ -1,8 +1,16 @@ -use std::{thread, sync::mpsc::{self, TryRecvError}, time::Duration, rc::Rc, cell::RefCell}; +use std::{ + sync::{ + mpsc::{self, TryRecvError}, + Arc, + Mutex, + }, + thread, + time::Duration, +}; use libmdns; -use Error; +use crate::Error; /// An mDNS Responder. Used to announce the Accessory's name and HAP TXT records to potential /// controllers. @@ -32,19 +40,16 @@ impl Responder { let tr = self.txt_records.clone(); thread::spawn(move || { let responder = libmdns::Responder::new().expect("couldn't create mDNS responder"); - let _svc = responder.register( - "_hap._tcp".into(), - name, - port, - &[&tr[0], &tr[1], &tr[2], &tr[3], &tr[4], &tr[5], &tr[6], &tr[7]], - ); + let _svc = responder.register("_hap._tcp".into(), name, port, &[ + &tr[0], &tr[1], &tr[2], &tr[3], &tr[4], &tr[5], &tr[6], &tr[7], + ]); loop { - thread::sleep(Duration::from_secs(10)); + thread::sleep(Duration::from_secs(2)); match rx.try_recv() { Ok(_) | Err(TryRecvError::Disconnected) => { break; - } - Err(TryRecvError::Empty) => {} + }, + Err(TryRecvError::Empty) => {}, } } }); @@ -69,4 +74,4 @@ impl Responder { } /// Reference counting pointer to a `Responder`. -pub type ResponderPtr = Rc>; +pub type ResponderPtr = Arc>; diff --git a/src/transport/mod.rs b/src/transport/mod.rs index 9ba6a81..1b41b51 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -1,15 +1,15 @@ -use db::{AccessoryListMember, AccessoryListPtr}; - -use Error; +use crate::{ + db::{AccessoryListMember, AccessoryListPtr}, + Error, +}; pub mod bonjour; pub mod mdns; pub(crate) mod http; -mod tcp; - mod ip; +mod tcp; pub use self::ip::IpTransport; @@ -21,7 +21,10 @@ pub trait Transport { /// Stops the transport. fn stop(&self) -> Result<(), Error>; /// Adds an Accessory to the transport and returns a pointer to the added Accessory. - fn add_accessory(&mut self, accessory: A) -> Result; + fn add_accessory( + &mut self, + accessory: A, + ) -> Result; /// Takes a pointer to an Accessory and removes the Accessory from the transport. fn remove_accessory(&mut self, accessory: &AccessoryListPtr) -> Result<(), Error>; } diff --git a/src/transport/tcp.rs b/src/transport/tcp.rs index 72b539c..0825a0f 100644 --- a/src/transport/tcp.rs +++ b/src/transport/tcp.rs @@ -1,24 +1,32 @@ -use std::{io::{self, Read, Write, ErrorKind}, cmp::min, rc::Rc, cell::RefCell}; +use std::{ + cmp::min, + io::{self, ErrorKind, Read, Write}, + sync::{Arc, Mutex}, +}; +use byteorder::{ByteOrder, LittleEndian}; +use bytes::{buf::FromBuf, BytesMut}; +use chacha20_poly1305_aead; use futures::{ - Async::{self, Ready, NotReady}, + sync::{ + mpsc::{self, UnboundedReceiver, UnboundedSender}, + oneshot, + }, + try_ready, + Async::{self, NotReady, Ready}, Future, Poll, - Stream, Sink, - sync::{oneshot, mpsc::{self, UnboundedSender, UnboundedReceiver}} + Stream, +}; +use ring::{digest, hkdf, hmac}; +use tokio::{ + io::{AsyncRead, AsyncWrite}, + net::TcpStream, }; -use tokio_core::net::TcpStream; -use tokio_io::{AsyncRead, AsyncWrite}; -use ring::{hkdf, hmac, digest}; -use chacha20_poly1305_aead; -use bytes::{BytesMut, buf::FromBuf}; -use byteorder::{ByteOrder, LittleEndian}; use uuid::Uuid; -use protocol::IdPtr; - -use Error; +use crate::{protocol::IdPtr, Error}; pub struct StreamWrapper { incoming_receiver: UnboundedReceiver>, @@ -31,7 +39,11 @@ impl StreamWrapper { incoming_receiver: UnboundedReceiver>, outgoing_sender: UnboundedSender>, ) -> StreamWrapper { - StreamWrapper { incoming_receiver, outgoing_sender, incoming_buf: BytesMut::new() } + StreamWrapper { + incoming_receiver, + outgoing_sender, + incoming_buf: BytesMut::new(), + } } fn poll_receiver(&mut self) -> Result { @@ -42,7 +54,8 @@ impl StreamWrapper { Ok(incoming.len()) }, Ok(Ready(None)) => Ok(0), - Err(_) => Err(Error::new_io("couldn't poll receiver").into()), + // Err(_) => Err(Error::from_str("couldn't poll receiver").into()), + Err(_) => Err(io::Error::new(io::ErrorKind::Other, "couldn't poll receiver")), } } } @@ -60,14 +73,16 @@ impl Read for StreamWrapper { impl Write for StreamWrapper { fn write(&mut self, buf: &[u8]) -> Result { self.outgoing_sender.unbounded_send(buf.to_vec()) - .map_err(|_| Error::new_io("couldn't write"))?; + // .map_err(|_| Error::from_str("couldn't write").into())?; + .map_err(|_| io::Error::new(io::ErrorKind::Other, "couldn't write"))?; Ok(buf.len()) } fn flush(&mut self) -> Result<(), io::Error> { self.outgoing_sender.poll_complete() .map(|_| ()) - .map_err(|_| Error::new_io("couldn't flush").into()) + // .map_err(|_| Error::from_str("couldn't flush").into()) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "couldn't flush")) } } @@ -105,7 +120,9 @@ pub struct EncryptedStream { } impl EncryptedStream { - pub fn new(stream: TcpStream) -> ( + pub fn new( + stream: TcpStream, + ) -> ( EncryptedStream, UnboundedReceiver>, UnboundedSender>, @@ -114,24 +131,29 @@ impl EncryptedStream { let (sender, receiver) = oneshot::channel(); let (incoming_sender, incoming_receiver) = mpsc::unbounded(); let (outgoing_sender, outgoing_receiver) = mpsc::unbounded(); - (EncryptedStream { - stream, - incoming_sender, - outgoing_receiver, - session_receiver: receiver, - controller_id: Rc::new(RefCell::new(None)), - shared_secret: None, - decrypt_count: 0, - encrypt_count: 0, - encrypted_buf: BytesMut::from_buf(vec![0; 1042]), - decrypted_buf: BytesMut::from_buf(vec![0; 1024]), - packet_len: 0, - already_copied: 0, - already_read: 0, - decrypted_ready: false, - missing_data_for_decrypted_buf: false, - missing_data_for_encrypted_buf: false, - }, incoming_receiver, outgoing_sender, sender) + ( + EncryptedStream { + stream, + incoming_sender, + outgoing_receiver, + session_receiver: receiver, + controller_id: Arc::new(Mutex::new(None)), + shared_secret: None, + decrypt_count: 0, + encrypt_count: 0, + encrypted_buf: BytesMut::from_buf(vec![0; 1042]), + decrypted_buf: BytesMut::from_buf(vec![0; 1024]), + packet_len: 0, + already_copied: 0, + already_read: 0, + decrypted_ready: false, + missing_data_for_decrypted_buf: false, + missing_data_for_encrypted_buf: false, + }, + incoming_receiver, + outgoing_sender, + sender, + ) } fn read_decrypted(&mut self, buf: &mut [u8]) -> Result { @@ -158,7 +180,8 @@ impl EncryptedStream { &self.encrypted_buf[2..(self.packet_len - 14)], &self.encrypted_buf[(self.packet_len - 14)..(self.packet_len + 2)], &mut self.decrypt_count, - )?; + ) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "decryption failed"))?; self.decrypted_buf[..decrypted.len()].copy_from_slice(&decrypted); self.missing_data_for_decrypted_buf = false; self.decrypted_ready = true; @@ -207,30 +230,50 @@ impl EncryptedStream { fn poll_incoming(&mut self) -> Poll<(), io::Error> { let mut data = [0; 1536]; loop { - let r_len = try_nb!(self.read(&mut data)); - if r_len == 0 { return Ok(Ready(())); } - self.incoming_sender.unbounded_send(data[..r_len].to_vec()) - .map_err(|_| Error::new_io("couldn't send incoming data"))?; + match self.read(&mut data) { + Err(e) => match e.kind() { + ErrorKind::WouldBlock => { + return Ok(NotReady); + }, + _ => { + return Err(e); + }, + }, + Ok(r_len) => { + if r_len == 0 { + return Ok(Ready(())); + } + self.incoming_sender.unbounded_send(data[..r_len].to_vec()) + // .map_err(|_| Error::from_str("couldn't send incoming data").into())?; + .map_err(|_| io::Error::new(io::ErrorKind::Other, "couldn't send incoming data"))?; + }, + } } } fn poll_outgoing(&mut self) -> Poll<(), ()> { loop { match try_ready!(self.outgoing_receiver.poll()) { - None => { return Ok(Ready(())); }, - Some(data) => { self.write(&data).map_err(|_| ())?; }, + None => { + return Ok(Ready(())); + }, + Some(data) => { + self.write(&data).map_err(|_| ())?; + }, } } } } impl Future for EncryptedStream { - type Item = (); type Error = io::Error; + type Item = (); fn poll(&mut self) -> Poll { self.poll_outgoing() - .map_err(|_| Error::new_io("couldn't receive outgoing data"))?; + // .map_err(|_| Error::from_str("couldn't receive outgoing data").into())?; + .map_err(|_| io::Error::new(io::ErrorKind::Other, "couldn't receive incoming data"))?; + self.poll_incoming() } } @@ -240,7 +283,7 @@ impl Read for EncryptedStream { if self.shared_secret.is_none() { match self.session_receiver.poll() { Ok(Async::Ready(session)) => { - self.controller_id.replace(Some(session.controller_id)); + *self.controller_id.lock().expect("couldn't access controller_id") = Some(session.controller_id); self.shared_secret = Some(session.shared_secret); }, _ => { @@ -265,22 +308,16 @@ impl Write for EncryptedStream { let mut write_buf = BytesMut::from_buf(buf); while write_buf.len() > 1024 { - let (aad, chunk, auth_tag) = encrypt_chunk( - &shared_secret, - &write_buf[..1024], - &mut self.encrypt_count, - )?; + let (aad, chunk, auth_tag) = encrypt_chunk(&shared_secret, &write_buf[..1024], &mut self.encrypt_count) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "encryption failed"))?; self.stream.write_all(&aad)?; self.stream.write_all(&chunk)?; self.stream.write_all(&auth_tag)?; write_buf.advance(1024); } - let (aad, chunk, auth_tag) = encrypt_chunk( - &shared_secret, - &write_buf, - &mut self.encrypt_count, - )?; + let (aad, chunk, auth_tag) = encrypt_chunk(&shared_secret, &write_buf, &mut self.encrypt_count) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "encryption failed"))?; // TODO - make this better self.stream.write_all(&aad)?; self.stream.write_all(&chunk)?; self.stream.write_all(&auth_tag)?; @@ -290,17 +327,13 @@ impl Write for EncryptedStream { } } - fn flush(&mut self) -> Result<(), io::Error> { - self.stream.flush() - } + fn flush(&mut self) -> Result<(), io::Error> { self.stream.flush() } } impl AsyncRead for EncryptedStream {} impl AsyncWrite for EncryptedStream { - fn shutdown(&mut self) -> Poll<(), io::Error> { - AsyncWrite::shutdown(&mut self.stream) - } + fn shutdown(&mut self) -> Poll<(), io::Error> { AsyncWrite::shutdown(&mut self.stream) } } fn decrypt_chunk( @@ -319,14 +352,7 @@ fn decrypt_chunk( nonce.extend(suffix); *count += 1; - chacha20_poly1305_aead::decrypt( - &read_key, - &nonce, - aad, - &data, - auth_tag, - &mut decrypted_data, - )?; + chacha20_poly1305_aead::decrypt(&read_key, &nonce, aad, &data, auth_tag, &mut decrypted_data)?; Ok(decrypted_data) } @@ -348,13 +374,7 @@ fn encrypt_chunk( let mut aad = [0; 2]; LittleEndian::write_u16(&mut aad, data.len() as u16); - let auth_tag = chacha20_poly1305_aead::encrypt( - &write_key, - &nonce, - &aad, - &data, - &mut encrypted_data, - )?; + let auth_tag = chacha20_poly1305_aead::encrypt(&write_key, &nonce, &aad, &data, &mut encrypted_data)?; Ok((aad, encrypted_data, auth_tag)) }