diff --git a/Cargo.lock b/Cargo.lock index d6a4adf..11627bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" + [[package]] name = "autocfg" version = "1.1.0" @@ -55,6 +70,29 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "serde", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -71,6 +109,85 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + [[package]] name = "dotenv" version = "0.15.0" @@ -90,6 +207,12 @@ dependencies = [ "spin 0.9.4", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "futures" version = "0.3.25" @@ -196,11 +319,66 @@ dependencies = [ name = "google-home" version = "0.1.0" dependencies = [ + "anyhow", "serde", "serde_json", + "serde_with", "uuid", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + [[package]] name = "itoa" version = "1.0.4" @@ -228,6 +406,15 @@ version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + [[package]] name = "lock_api" version = "0.4.9" @@ -274,6 +461,25 @@ dependencies = [ "getrandom", ] +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.16.0" @@ -439,6 +645,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "sct" version = "0.7.0" @@ -503,6 +715,34 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "slab" version = "0.4.7" @@ -537,6 +777,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.105" @@ -548,6 +794,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + [[package]] name = "thiserror" version = "1.0.37" @@ -568,6 +823,33 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "tokio" version = "1.23.0" @@ -613,6 +895,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "untrusted" version = "0.7.1" @@ -725,6 +1013,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/google-home/Cargo.lock b/google-home/Cargo.lock index 4c283ad..387e207 100644 --- a/google-home/Cargo.lock +++ b/google-home/Cargo.lock @@ -2,12 +2,165 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "num-integer", + "num-traits", + "serde", + "winapi", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "getrandom" version = "0.2.8" @@ -23,23 +176,130 @@ dependencies = [ name = "google-home" version = "0.1.0" dependencies = [ + "anyhow", "serde", "serde_json", + "serde_with", "uuid", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + [[package]] name = "itoa" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + [[package]] name = "proc-macro2" version = "1.0.47" @@ -64,6 +324,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + [[package]] name = "serde" version = "1.0.149" @@ -95,6 +361,40 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bf4a5a814902cd1014dbccfa4d4560fb8432c779471e96e035602519f82eef" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3452b4c0f6c1e357f73fdb87cd1efabaa12acf328c7a528e252893baeb3f4aa" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.105" @@ -106,12 +406,54 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + [[package]] name = "unicode-ident" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "uuid" version = "1.2.2" @@ -127,3 +469,88 @@ name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/google-home/Cargo.toml b/google-home/Cargo.toml index 0908707..873c359 100644 --- a/google-home/Cargo.toml +++ b/google-home/Cargo.toml @@ -6,8 +6,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow = "1.0" serde = { version ="1.0.149", features = ["derive"] } serde_json = "1.0.89" +serde_with = "2.1.0" [dependencies.uuid] version = "1.2.2" diff --git a/google-home/src/attributes.rs b/google-home/src/attributes.rs new file mode 100644 index 0000000..6ab43d6 --- /dev/null +++ b/google-home/src/attributes.rs @@ -0,0 +1,11 @@ +use serde::Serialize; +use serde_with::skip_serializing_none; + +#[skip_serializing_none] +#[derive(Debug, Default, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Attributes { + pub command_only_on_off: Option, + pub query_only_on_off: Option, + pub scene_reversible: Option, +} diff --git a/google-home/src/device.rs b/google-home/src/device.rs new file mode 100644 index 0000000..881ec90 --- /dev/null +++ b/google-home/src/device.rs @@ -0,0 +1,96 @@ +use serde::Serialize; +use serde_with::skip_serializing_none; + +use crate::{response, types::Type, traits::{AsOnOff, Trait, AsScene}}; + +pub trait GoogleHomeDevice: AsOnOff + AsScene { + fn get_device_type(&self) -> Type; + fn get_device_name(&self) -> Name; + fn get_id(&self) -> &str; + + // Default values that can optionally be overriden + fn will_report_state(&self) -> bool { + false + } + fn get_room_hint(&self) -> Option { + None + } + fn get_device_info(&self) -> Option { + None + } +} + +// This trait exists just to hide the sync, query and execute function from the user +pub trait GoogleHomeDeviceFullfillment: GoogleHomeDevice { + fn sync(&self) -> response::sync::Device { + let name = self.get_device_name(); + let mut device = response::sync::Device::new(&self.get_id(), &name.name, self.get_device_type()); + + device.name = name; + device.will_report_state = self.will_report_state(); + // notification_supported_by_agent + device.room_hint = self.get_room_hint(); + device.device_info = self.get_device_info(); + + let mut traits = Vec::new(); + // OnOff + { + if let Some(d) = AsOnOff::cast(self) { + traits.push(Trait::OnOff); + device.attributes.command_only_on_off = d.is_command_only(); + device.attributes.query_only_on_off = d.is_query_only(); + } + } + + // Scene + { + if let Some(d) = AsScene::cast(self) { + traits.push(Trait::Scene); + device.attributes.scene_reversible = d.is_scene_reversible(); + } + } + + device.traits = traits; + + return device; + } +} + +impl GoogleHomeDeviceFullfillment for T {} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Name { + #[serde(skip_serializing_if = "Vec::is_empty")] + default_names: Vec, + name: String, + #[serde(skip_serializing_if = "Vec::is_empty")] + nicknames: Vec, +} + +impl Name { + pub fn new(name: &str) -> Self { + Self { default_names: Vec::new(), name: name.into(), nicknames: Vec::new() } + } + + pub fn add_default_name(&mut self, name: &str) { + self.default_names.push(name.into()); + } + + pub fn add_nickname(&mut self, name: &str) { + self.nicknames.push(name.into()); + } +} + +#[skip_serializing_none] +#[derive(Debug, Default, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Info { + pub manufacturer: Option, + pub model: Option, + pub hw_version: Option, + pub sw_version: Option, + // attributes + // customData + // otherDeviceIds +} diff --git a/google-home/src/fullfillment.rs b/google-home/src/fullfillment.rs new file mode 100644 index 0000000..2a07bc9 --- /dev/null +++ b/google-home/src/fullfillment.rs @@ -0,0 +1,169 @@ +use crate::{request::{Request, Intent, self}, device::GoogleHomeDeviceFullfillment, response::{sync, ResponsePayload, query, execute, Response}}; + +pub struct GoogleHome { + user_id: String, + // Add credentials so we can notify google home of actions +} + +impl GoogleHome { + pub fn new(user_id: &str) -> Self { + Self { user_id: user_id.into() } + } + + pub fn handle_request(&self, request: Request, devices: Vec<&mut dyn GoogleHomeDeviceFullfillment>) -> Result { + // @TODO What do we do if we actually get more then one thing in the input array, right now + // we only respond to the first thing + let payload = request + .inputs + .into_iter() + .map(|input| match input { + Intent::Sync => ResponsePayload::Sync(self.sync(&devices)), + Intent::Query(payload) => ResponsePayload::Query(self.query(payload, &devices)), + Intent::Execute(payload) => ResponsePayload::Execute(self.execute(payload, &devices)), + }).next(); + + match payload { + Some(payload) => Ok(Response::new(request.request_id, payload)), + _ => Err(anyhow::anyhow!("Something went wrong, expected at least ResponsePayload")), + } + } + + fn sync(&self, devices: &Vec<&mut dyn GoogleHomeDeviceFullfillment>) -> sync::Payload { + let mut payload = sync::Payload::new(&self.user_id); + payload.devices = devices.iter().map(|device| device.sync()).collect::>(); + + return payload; + } + + fn query(&self, payload: request::query::Payload, devices: &Vec<&mut dyn GoogleHomeDeviceFullfillment>) -> query::Payload { + return query::Payload::new(); + } + + fn execute(&self, payload: request::execute::Payload, devices: &Vec<&mut dyn GoogleHomeDeviceFullfillment>) -> execute::Payload { + return execute::Payload::new(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{request::Request, device::{GoogleHomeDevice, self}, types, traits}; + + struct TestOutlet { + on: bool, + } + + impl TestOutlet { + fn new() -> Self { + Self { on: false } + } + } + + impl GoogleHomeDevice for TestOutlet { + fn get_device_type(&self) -> types::Type { + types::Type::Outlet + } + + fn get_device_name(&self) -> device::Name { + let mut name = device::Name::new("Nightstand"); + name.add_default_name("Outlet"); + name.add_nickname("Nightlight"); + + return name; + } + + fn get_id(&self) -> &str { + return "bedroom/nightstand"; + } + + fn get_room_hint(&self) -> Option { + Some("Bedroom".into()) + } + + fn get_device_info(&self) -> Option { + Some(device::Info { + manufacturer: Some("Company".into()), + model: Some("Outlet II".into()), + hw_version: None, + sw_version: None, + }) + } + } + + impl traits::OnOff for TestOutlet { + fn is_on(&self) -> Result { + Ok(self.on) + } + + fn set_on(&mut self, on: bool) -> Result<(), anyhow::Error> { + self.on = on; + Ok(()) + } + } + + impl traits::AsScene for TestOutlet {} + + + struct TestScene {} + + impl TestScene { + fn new() -> Self { + Self {} + } + } + + impl GoogleHomeDevice for TestScene { + fn get_device_type(&self) -> types::Type { + types::Type::Scene + } + + fn get_device_name(&self) -> device::Name { + device::Name::new("Party") + } + + fn get_id(&self) -> &str { + return "living/party_mode"; + } + + fn get_room_hint(&self) -> Option { + Some("Living room".into()) + } + } + + impl traits::Scene for TestScene { + fn set_active(&self, _activate: bool) -> Result<(), anyhow::Error> { + println!("Activating the party scene"); + Ok(()) + } + } + + impl traits::AsOnOff for TestScene {} + + + + #[test] + fn handle_sync() { + let json = r#"{ + "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf", + "inputs": [ + { + "intent": "action.devices.SYNC" + } + ] +}"#; + let req: Request = serde_json::from_str(json).unwrap(); + + let gh = GoogleHome { + user_id: "Dreaded_X".into(), + }; + + let mut device = TestOutlet::new(); + let mut scene = TestScene::new(); + let devices: Vec<&mut dyn GoogleHomeDeviceFullfillment> = vec![&mut device, &mut scene]; + + let resp = gh.handle_request(req, devices).unwrap(); + + let json = serde_json::to_string(&resp).unwrap(); + println!("{}", json) + } +} diff --git a/google-home/src/lib.rs b/google-home/src/lib.rs index 948cafd..4253cad 100644 --- a/google-home/src/lib.rs +++ b/google-home/src/lib.rs @@ -1,4 +1,9 @@ +pub mod fullfillment; +pub mod device; + pub mod request; pub mod response; + pub mod types; pub mod traits; +pub mod attributes; diff --git a/google-home/src/request.rs b/google-home/src/request.rs index 5959e74..1b2c873 100644 --- a/google-home/src/request.rs +++ b/google-home/src/request.rs @@ -7,7 +7,7 @@ use uuid::Uuid; #[derive(Debug, Deserialize)] #[serde(tag = "intent", content = "payload")] -enum Intent { +pub enum Intent { #[serde(rename = "action.devices.SYNC")] Sync, #[serde(rename = "action.devices.QUERY")] @@ -18,7 +18,7 @@ enum Intent { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] -struct Request { +pub struct Request { pub request_id: Uuid, pub inputs: Vec, } diff --git a/google-home/src/request/execute.rs b/google-home/src/request/execute.rs index a6cbe6c..c37b697 100644 --- a/google-home/src/request/execute.rs +++ b/google-home/src/request/execute.rs @@ -27,6 +27,10 @@ pub enum CommandType { OnOff { on: bool }, + #[serde(rename = "action.devices.commands.ActivateScene")] + ActivateScene { + deactivate: bool + } } #[cfg(test)] @@ -95,7 +99,7 @@ mod tests { assert_eq!(payload.commands[0].execution.len(), 1); match payload.commands[0].execution[0] { CommandType::OnOff{on} => assert_eq!(on, true), - // _ => panic!("Expected OnOff") + _ => panic!("Expected OnOff") } }, _ => panic!("Expected Execute intent") diff --git a/google-home/src/response.rs b/google-home/src/response.rs index 0d56ca9..6a9a693 100644 --- a/google-home/src/response.rs +++ b/google-home/src/response.rs @@ -3,6 +3,7 @@ pub mod query; pub mod execute; use serde::Serialize; +use serde_with::skip_serializing_none; use uuid::Uuid; #[derive(Debug, Serialize)] @@ -13,7 +14,7 @@ pub struct Response { } impl Response { - fn new(request_id: Uuid, payload: ResponsePayload) -> Self { + pub fn new(request_id: Uuid, payload: ResponsePayload) -> Self { Self { request_id, payload } } } @@ -26,10 +27,10 @@ pub enum ResponsePayload { Execute(execute::Payload), } +#[skip_serializing_none] #[derive(Debug, Default, Serialize)] #[serde(rename_all = "camelCase")] pub struct State { - #[serde(skip_serializing_if = "Option::is_none")] on: Option, } diff --git a/google-home/src/response/execute.rs b/google-home/src/response/execute.rs index 7d8c054..c1fbc3a 100644 --- a/google-home/src/response/execute.rs +++ b/google-home/src/response/execute.rs @@ -1,13 +1,13 @@ use serde::Serialize; +use serde_with::skip_serializing_none; use crate::response::State; +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Payload { - #[serde(skip_serializing_if = "Option::is_none")] pub error_code: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub debug_string: Option, commands: Vec, } @@ -22,10 +22,10 @@ impl Payload { } } +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Command { - #[serde(skip_serializing_if = "Option::is_none")] pub error_code: Option, ids: Vec, diff --git a/google-home/src/response/query.rs b/google-home/src/response/query.rs index 8fd0425..d664ee5 100644 --- a/google-home/src/response/query.rs +++ b/google-home/src/response/query.rs @@ -1,15 +1,15 @@ use std::collections::HashMap; use serde::Serialize; +use serde_with::skip_serializing_none; use crate::response::State; +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Payload { - #[serde(skip_serializing_if = "Option::is_none")] pub error_code: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub debug_string: Option, devices: HashMap, } @@ -33,12 +33,12 @@ pub enum Status { Error, } +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Device { online: bool, status: Status, - #[serde(skip_serializing_if = "Option::is_none")] pub error_code: Option, #[serde(flatten)] diff --git a/google-home/src/response/sync.rs b/google-home/src/response/sync.rs index 18221ff..ff4756f 100644 --- a/google-home/src/response/sync.rs +++ b/google-home/src/response/sync.rs @@ -1,15 +1,17 @@ use serde::Serialize; +use serde_with::skip_serializing_none; +use crate::attributes::Attributes; +use crate::device; use crate::types::Type; use crate::traits::Trait; +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Payload { agent_user_id: String, - #[serde(skip_serializing_if = "Option::is_none")] pub error_code: Option, - #[serde(skip_serializing_if = "Option::is_none")] pub debug_string: Option, pub devices: Vec, } @@ -24,6 +26,7 @@ impl Payload { } } +#[skip_serializing_none] #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Device { @@ -31,16 +34,12 @@ pub struct Device { #[serde(rename = "type")] device_type: Type, pub traits: Vec, - pub name: DeviceName, + pub name: device::Name, pub will_report_state: bool, - #[serde(skip_serializing_if = "Option::is_none")] pub notification_supported_by_agent: Option, - #[serde(skip_serializing_if = "String::is_empty")] - pub room_hint: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub device_info: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub attributes: Option, + pub room_hint: Option, + pub device_info: Option, + pub attributes: Attributes, } impl Device { @@ -49,51 +48,16 @@ impl Device { id: id.into(), device_type, traits: Vec::new(), - name: DeviceName { - default_names: Vec::new(), - name: name.into(), - nicknames: Vec::new() }, + name: device::Name::new(name), will_report_state: false, notification_supported_by_agent: None, - room_hint: "".into(), + room_hint: None, device_info: None, - attributes: None, + attributes: Attributes::default(), } } } -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct DeviceName { - #[serde(skip_serializing_if = "Vec::is_empty")] - pub default_names: Vec, - name: String, - #[serde(skip_serializing_if = "Vec::is_empty")] - pub nicknames: Vec, -} - -#[derive(Debug, Default, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct DeviceInfo { - #[serde(skip_serializing_if = "String::is_empty")] - pub manufacturer: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub model: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub hw_version: String, - #[serde(skip_serializing_if = "String::is_empty")] - pub sw_version: String, - // attributes - // customData - // otherDeviceIds -} - -#[derive(Debug, Default, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct Attributes { - -} - #[cfg(test)] mod tests { use std::str::FromStr; @@ -107,15 +71,15 @@ mod tests { let mut device = Device::new("123", "Night light", Type::Kettle); device.traits.push(Trait::OnOff); - device.name.default_names.push("My Outlet 1234".to_string()); - device.name.nicknames.push("wall plug".to_string()); + device.name.add_default_name("My Outlet 1234"); + device.name.add_nickname("wall plug"); - device.room_hint = "kitchen".into(); - device.device_info = Some(DeviceInfo { - manufacturer: "lights-out-inc".to_string(), - model: "hs1234".to_string(), - hw_version: "3.2".to_string(), - sw_version: "11.4".to_string(), + device.room_hint = Some("kitchen".into()); + device.device_info = Some(device::Info { + manufacturer: Some("lights-out-inc".to_string()), + model: Some("hs1234".to_string()), + hw_version: Some("3.2".to_string()), + sw_version: Some("11.4".to_string()), }); sync_resp.add_device(device); diff --git a/google-home/src/traits.rs b/google-home/src/traits.rs index 3cdcb4d..a867c63 100644 --- a/google-home/src/traits.rs +++ b/google-home/src/traits.rs @@ -1,5 +1,7 @@ use serde::Serialize; +use crate::device::GoogleHomeDevice; + #[derive(Debug, Serialize)] pub enum Trait { #[serde(rename = "action.devices.traits.OnOff")] @@ -7,3 +9,58 @@ pub enum Trait { #[serde(rename = "action.devices.traits.Scene")] Scene, } + +pub trait OnOff { + fn is_command_only(&self) -> Option { + None + } + + fn is_query_only(&self) -> Option { + None + } + + // @TODO Implement correct error so we can handle them properly + fn is_on(&self) -> Result; + fn set_on(&mut self, on: bool) -> Result<(), anyhow::Error>; +} +pub trait AsOnOff { + fn cast(&self) -> Option<&dyn OnOff> { + None + } + fn cast_mut(&mut self) -> Option<&mut dyn OnOff> { + None + } +} +impl AsOnOff for T { + fn cast(&self) -> Option<&dyn OnOff> { + Some(self) + } + fn cast_mut(&mut self) -> Option<&mut dyn OnOff> { + Some(self) + } +} + + +pub trait Scene { + fn is_scene_reversible(&self) -> Option { + None + } + + fn set_active(&self, activate: bool) -> Result<(), anyhow::Error>; +} +pub trait AsScene { + fn cast(&self) -> Option<&dyn Scene> { + None + } + fn cast_mut(&mut self) -> Option<&mut dyn Scene> { + None + } +} +impl AsScene for T { + fn cast(&self) -> Option<&dyn Scene> { + Some(self) + } + fn cast_mut(&mut self) -> Option<&mut dyn Scene> { + Some(self) + } +}