diff --git a/Cargo.lock b/Cargo.lock index b5eaee4..8ee65dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.0.0-rc.2" +version = "4.0.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73170d019de2d82c0d826c1f315c3106134bd764e9247505ba6f0d78d22dfe9e" +checksum = "d7bfa913583b6cfe5f0d1588e752bcf6b107556422624fefdaf99c40ba2b7f16" dependencies = [ "actix-codec 0.4.2", "actix-http 3.0.0-rc.1", @@ -551,12 +551,123 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "anyhow" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" + [[package]] name = "arrayvec" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "once_cell", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-mutex", + "blocking", + "futures-lite", + "num_cpus", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log", + "once_cell", + "parking", + "polling", + "slab", + "socket2 0.4.4", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-lock" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "num_cpus", + "once_cell", + "pin-project-lite 0.2.8", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" version = "0.3.2" @@ -578,6 +689,12 @@ dependencies = [ "syn", ] +[[package]] +name = "async-task" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d306121baf53310a3fd342d88dc0824f6bbeace68347593658525565abee8" + [[package]] name = "async-trait" version = "0.1.52" @@ -598,6 +715,32 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "atomic-waker" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -653,12 +796,39 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -677,6 +847,20 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" +dependencies = [ + "async-channel", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "once_cell", +] + [[package]] name = "brotli" version = "3.3.3" @@ -731,6 +915,88 @@ dependencies = [ "bytes 1.1.0", ] +[[package]] +name = "cache-padded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" + +[[package]] +name = "camino" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-embed" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af78296bef5b5beffafbc95b128019e493b135aebd41a9af016640a346bbd070" +dependencies = [ + "anyhow", + "chrono", + "colored", + "crossterm 0.22.1", + "defmt-decoder", + "env_logger", + "figment", + "gdb-server", + "git-version", + "goblin", + "lazy_static", + "log", + "probe-rs", + "probe-rs-cli-util", + "probe-rs-rtt", + "serde", + "serde_json", + "structopt", + "textwrap 0.14.2", + "tui", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ae6de944143141f6155a473a6b02f66c7c3f9f47316f802f80204ebfe6e12" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.4", + "serde", + "serde_json", +] + +[[package]] +name = "cargo_toml" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363c7cfaa15f101415c4ac9e68706ca4a2277773932828b33f96e59d28c68e62" +dependencies = [ + "serde", + "serde_derive", + "toml", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + [[package]] name = "cc" version = "1.0.72" @@ -766,6 +1032,54 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "colored" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +dependencies = [ + "atty", + "lazy_static", + "winapi 0.3.9", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "terminal_size", + "winapi 0.3.9", +] + [[package]] name = "const_fn" version = "0.4.9" @@ -885,6 +1199,56 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crossterm" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebde6a9dd5e331cd6c6f48253254d117642c31653baa475e394657c59c1f7d" +dependencies = [ + "bitflags", + "crossterm_winapi 0.8.0", + "libc", + "mio 0.7.14", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85525306c4291d1b73ce93c8acf9c339f9b213aef6c1d85c3830cbf1c16325c" +dependencies = [ + "bitflags", + "crossterm_winapi 0.9.0", + "libc", + "mio 0.7.14", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi 0.3.9", +] + +[[package]] +name = "crossterm_winapi" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6966607622438301997d3dac0d2f6e9a90c68bb6bc1785ea98456ab93c0507" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "crypto-common" version = "0.1.1" @@ -894,6 +1258,42 @@ dependencies = [ "generic-array", ] +[[package]] +name = "ctor" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "defmt-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d5765366c461413e5b2966b89f14bbdb3f5d785fd03f1cfe8261fcfcac6844" +dependencies = [ + "anyhow", + "byteorder", + "chrono", + "colored", + "defmt-parser", + "difference", + "gimli", + "log", + "object", + "ryu", + "serde", + "serde_json", +] + +[[package]] +name = "defmt-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d1ce010e1a51aef925c98f12ed81a4e0e96ce0185a87c33f1b3b9c8f20749c7" + [[package]] name = "derive_more" version = "0.99.17" @@ -907,6 +1307,12 @@ dependencies = [ "syn", ] +[[package]] +name = "difference" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" + [[package]] name = "digest" version = "0.9.0" @@ -939,12 +1345,24 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dunce" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" + [[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.30" @@ -966,6 +1384,42 @@ dependencies = [ "syn", ] +[[package]] +name = "enum-primitive-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" +dependencies = [ + "num-traits", + "quote", + "syn", +] + +[[package]] +name = "env_logger" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "event-listener" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fastrand" version = "1.7.0" @@ -975,6 +1429,22 @@ dependencies = [ "instant", ] +[[package]] +name = "figment" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790b4292c72618abbab50f787a477014fe15634f96291de45672ce46afe122df" +dependencies = [ + "atomic", + "pear", + "serde", + "serde_json", + "serde_yaml", + "toml", + "uncased", + "version_check", +] + [[package]] name = "firestorm" version = "0.5.0" @@ -1052,6 +1522,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "funty" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" + [[package]] name = "futures" version = "0.3.19" @@ -1111,6 +1587,21 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite 0.2.8", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.19" @@ -1161,6 +1652,32 @@ dependencies = [ "byteorder", ] +[[package]] +name = "gdb-protocol" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8b88b222a91266bb192222d46d0da29addbc423d0a9910aec233dce875eb6e" +dependencies = [ + "memchr", +] + +[[package]] +name = "gdb-server" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b862cca390b0b773a3818698add753a8c37e200393020cba0d3b4c9eed0af7b" +dependencies = [ + "anyhow", + "async-std", + "futures", + "gdb-protocol", + "hex", + "log", + "memchr", + "nom", + "probe-rs", +] + [[package]] name = "generic-array" version = "0.14.5" @@ -1193,6 +1710,61 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +dependencies = [ + "fallible-iterator", + "stable_deref_trait", +] + +[[package]] +name = "git-version" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +dependencies = [ + "git-version-macro", + "proc-macro-hack", +] + +[[package]] +name = "git-version-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gloo-timers" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d12a7f4e95cfe710f1d624fb1210b7d961a5fb05c4fd942f4feab06e61f590e" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "goblin" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32401e89c6446dcd28185931a01b1093726d0356820ac744023e6850689bf926" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "h2" version = "0.2.7" @@ -1274,6 +1846,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hidapi" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c4cc7279df8353788ac551186920e44959d5948aec404be02b28544a598bce" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + [[package]] name = "hostname" version = "0.3.1" @@ -1308,6 +1891,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "idna" version = "0.2.3" @@ -1319,6 +1908,12 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "ihex" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "365a784774bb381e8c19edb91190a90d7f2625e057b55de2bc0f6b57bc779ff2" + [[package]] name = "indexmap" version = "1.8.0" @@ -1329,6 +1924,24 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "indicatif" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "regex", +] + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + [[package]] name = "instant" version = "0.1.12" @@ -1380,6 +1993,27 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +[[package]] +name = "jaylink" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f58b72b6aa9d25083b8c19d292fe015a936185fa200d15e225e1524a18222e9" +dependencies = [ + "bitflags", + "byteorder", + "log", + "rusb", +] + +[[package]] +name = "jep106" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e80f965a2a659a7a4d9cdb9821a869d6e33c10f3e094e8f7d01648063c425953" +dependencies = [ + "serde", +] + [[package]] name = "jobserver" version = "0.1.24" @@ -1389,6 +2023,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -1399,6 +2042,15 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "language-tags" version = "0.2.2" @@ -1434,6 +2086,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libusb1-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.4" @@ -1474,6 +2138,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ "cfg-if 1.0.0", + "serde", + "value-bag", ] [[package]] @@ -1491,6 +2157,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.9" @@ -1700,6 +2375,21 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.9.0" @@ -1769,6 +2459,12 @@ dependencies = [ "syn", ] +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.11.2" @@ -1800,6 +2496,29 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +[[package]] +name = "pear" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e44241c5e4c868e3eaa78b7c1848cadd6344ed4f54d029832d32b415a58702" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi", +] + +[[package]] +name = "pear_codegen" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82a5ca643c2303ecb740d506539deba189e16f2754040a42901cd8105d0282d0" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1870,12 +2589,109 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "polling" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "winapi 0.3.9", +] + [[package]] name = "ppv-lite86" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +[[package]] +name = "probe-rs" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "232e7f2912aba17bef48f84f9d90bfc9e6c1d8c90959fcf1451ccb3a68819ee7" +dependencies = [ + "anyhow", + "base64", + "bincode", + "bitfield", + "bitvec", + "enum-primitive-derive", + "gimli", + "hidapi", + "ihex", + "jaylink", + "jep106", + "log", + "num-traits", + "object", + "once_cell", + "probe-rs-target", + "rusb", + "scroll", + "serde", + "serde_yaml", + "static_assertions", + "svg", + "thiserror", + "thousands", +] + +[[package]] +name = "probe-rs-cli-util" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727e80b14050d99a7dac18f87abee5ef72fe479fe534ed73524299ae3d4f3312" +dependencies = [ + "anyhow", + "cargo_metadata", + "cargo_toml", + "colored", + "dunce", + "env_logger", + "indicatif", + "log", + "once_cell", + "probe-rs", + "serde", + "simplelog", + "structopt", + "terminal_size", + "thiserror", +] + +[[package]] +name = "probe-rs-rtt" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17a9f49ddd5fa2f079961debbea5f93e4fc168bf89223a0407aa9de60eed8d51" +dependencies = [ + "log", + "probe-rs", + "scroll", + "thiserror", +] + +[[package]] +name = "probe-rs-target" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f9610234697e695947df2f7b0cd71d4e4e2fe2fea13df90bdc44bb65e0ef16f" +dependencies = [ + "base64", + "jep106", + "serde", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1915,6 +2731,19 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", + "yansi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1930,6 +2759,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + [[package]] name = "rand" version = "0.7.3" @@ -2031,6 +2866,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.25" @@ -2056,6 +2900,16 @@ dependencies = [ "quick-error", ] +[[package]] +name = "rusb" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9a5084628cc5be77b1c750b3e5ee0cc519d2f2491b3f06b78b3aac3328b00ad" +dependencies = [ + "libc", + "libusb1-sys", +] + [[package]] name = "rust_decimal" version = "1.21.0" @@ -2113,6 +2967,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scroll" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda28d4b4830b807a8b43f7b0e6b5df875311b3e7621d84577188c175b6ec1ec" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaaae8f38bb311444cfb7f1979af0bc9240d95795f75f9ceddf6a59b79ceffa0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "sea-orm" version = "0.5.0" @@ -2236,6 +3110,9 @@ name = "semver" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -2287,6 +3164,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -2348,6 +3237,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "647c97df271007dcea485bb74ffdb57f2e683f1306c854f468a0c244badabf2d" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +dependencies = [ + "libc", + "mio 0.7.14", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -2357,6 +3267,17 @@ dependencies = [ "libc", ] +[[package]] +name = "simplelog" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1348164456f72ca0116e4538bdaabb0ddb622c7d9f16387c725af3e96d6001c" +dependencies = [ + "chrono", + "log", + "termcolor", +] + [[package]] name = "slab" version = "0.4.5" @@ -2369,6 +3290,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +[[package]] +name = "smawk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + [[package]] name = "socket2" version = "0.3.19" @@ -2517,6 +3444,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stdweb" version = "0.4.20" @@ -2576,6 +3509,42 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "svg" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e72d8b19ab05827afefcca66bf47040c1e66a0901eb814784c77d4ec118bd309" + [[package]] name = "syn" version = "1.0.86" @@ -2587,6 +3556,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.3.0" @@ -2601,6 +3576,45 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.30" @@ -2621,6 +3635,12 @@ dependencies = [ "syn", ] +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + [[package]] name = "thread_local" version = "1.1.4" @@ -2807,6 +3827,15 @@ dependencies = [ "tokio 1.16.1", ] +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + [[package]] name = "tracing" version = "0.1.29" @@ -2820,6 +3849,19 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-actix-web" +version = "0.5.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066b8102bdd05325d02966fac8b5e360eafd8dcdf81006c4d30f3543f488714" +dependencies = [ + "actix-web 4.0.0-rc.1", + "pin-project 1.0.10", + "tracing", + "tracing-futures", + "uuid", +] + [[package]] name = "tracing-attributes" version = "0.1.18" @@ -2868,13 +3910,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5312f325fe3588e277415f5a6cca1f4ccad0f248c4cd5a4bd33032d7286abc22" dependencies = [ "ansi_term", + "lazy_static", + "matchers", + "regex", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] +[[package]] +name = "tracing-test" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb7bda2e93bbc9c5b247034acc6a4b3d04f033a3d4b8fc1cb87d4d1c7c7ebd7" +dependencies = [ + "lazy_static", + "tracing-core", + "tracing-subscriber", + "tracing-test-macro", +] + +[[package]] +name = "tracing-test-macro" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4801dca35e4e2cee957c469bd4a1c370fadb7894c0d50721a40eba3523e6e91c" +dependencies = [ + "lazy_static", + "quote", + "syn", +] + [[package]] name = "tracing-unwrap" version = "0.9.2" @@ -2923,18 +3992,49 @@ dependencies = [ "trust-dns-proto", ] +[[package]] +name = "tui" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c8ce4e27049eed97cfa363a5048b09d995e209994634a0efc26a14ab6c0c23" +dependencies = [ + "bitflags", + "cassowary", + "crossterm 0.20.0", + "unicode-segmentation", + "unicode-width", +] + [[package]] name = "typenum" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "uncased" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baeed7327e25054889b9bd4f975f32e5f4c5d434042d59ab6cd4142c0a76ed0" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-linebreak" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" +dependencies = [ + "regex", +] + [[package]] name = "unicode-normalization" version = "0.1.19" @@ -2950,6 +4050,12 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -2991,28 +4097,53 @@ dependencies = [ "actix", "actix-cors", "actix-rt 2.6.0", - "actix-web 4.0.0-rc.2", + "actix-web 4.0.0-rc.1", + "cargo-embed", "chrono", "sea-orm", "serde", "serde_json", "tracing", + "tracing-actix-web", "tracing-subscriber", + "tracing-test", "tracing-unwrap", ] +[[package]] +name = "value-bag" +version = "1.0.0-alpha.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" +dependencies = [ + "ctor", + "version_check", +] + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -3050,6 +4181,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.79" @@ -3079,6 +4222,25 @@ version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +[[package]] +name = "web-sys" +version = "0.3.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "widestring" version = "0.4.3" @@ -3113,6 +4275,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 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -3138,6 +4309,30 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "wyz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "yansi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" + [[package]] name = "zstd" version = "0.9.2+zstd.1.5.1" diff --git a/Cargo.toml b/Cargo.toml index 8c0505c..eadc801 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,5 +15,8 @@ actix-cors = "0.5.4" chrono = { version = "0.4.19", features = ["serde"] } serde = { version = "1.0.136", features= [ "derive" ] } serde_json = "1.0.78" -actix-web = "4.0.0-rc.2" +actix-web = "4.0.0-rc.1" actix-rt = "2.6.0" +tracing-test = "0.2.1" +tracing-actix-web = "0.5.0-rc.1" +cargo-embed = "0.12.0" diff --git a/Makefile.toml b/Makefile.toml index 647f1ac..a827168 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -15,7 +15,7 @@ command = "sqlx" args = ["migrate", "run"] [tasks.resetdb] -run_task = { name = ["dropdb", "createdb", "migratedb", "entity"] } +run_task = { name = ["dropdb", "createdb", "migratedb"] } [tasks.entity] command = "sea-orm-cli" diff --git a/migrations/20220203034730_create-apps-table.sql b/migrations/20220203034730_create-apps-table.sql index ed3748a..28e37b8 100644 --- a/migrations/20220203034730_create-apps-table.sql +++ b/migrations/20220203034730_create-apps-table.sql @@ -1,5 +1,27 @@ -- Add migration script here -CREATE TABLE application ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, app_name TEXT NOT NULL, url TEXT NOT NULL, description TEXT, active Boolean NOT NULL DEFAULT 1, glyph TEXT, application_category_id INTEGER); -CREATE TABLE application_category ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, category_name TEXT NOT NULL, active BOOLEAN NOT NULL DEFAULT 1 ); -CREATE TABLE bookmark ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, category_name TEXT NOT NULL, active BOOLEAN NOT NULL DEFAULT 1, glyph TEXT, bookmark_category_id INTEGER); -CREATE TABLE bookmark_category ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, category_name TEXT NOT NULL, active BOOLEAN NOT NULL DEFAULT 1, glyph TEXT ); +CREATE TABLE application ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + app_name TEXT NOT NULL, + url TEXT NOT NULL, + description TEXT, + active Boolean NOT NULL DEFAULT 1, + glyph TEXT, + application_category_id INTEGER +); +CREATE TABLE application_category ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + category_name TEXT NOT NULL, + active BOOLEAN NOT NULL DEFAULT 1 +); +CREATE TABLE bookmark ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + category_name TEXT NOT NULL, + active BOOLEAN NOT NULL DEFAULT 1, + glyph TEXT, bookmark_category_id INTEGER +); +CREATE TABLE bookmark_category ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + category_name TEXT NOT NULL, + active BOOLEAN NOT NULL DEFAULT 1, + glyph TEXT +); diff --git a/src/api/application_category.rs b/src/api/application_category.rs new file mode 100644 index 0000000..4be546b --- /dev/null +++ b/src/api/application_category.rs @@ -0,0 +1,324 @@ +use tracing::instrument; + +use crate::api::api_prelude::*; +use crate::error::{Error, Result}; + +#[instrument] +#[get("")] +pub async fn list_application_categories(state: web::Data) -> Result { + let cats: Vec = + ApplicationCategory::find().all(&state.db).await.unwrap(); + let count = cats.len(); + Ok(HttpResponse::Ok().json(ListObjects::new(cats, count))) +} + +#[instrument] +#[post("")] +pub async fn new_application_category( + state: web::Data, + data: web::Json, +) -> Result { + let model = application_category::ActiveModel { + id: NotSet, + category_name: Set(data.0.category_name), + active: Set(data.0.active), + }; + let rec = model.insert(&state.db).await?; + Ok(HttpResponse::Ok().json(rec)) +} + +#[instrument] +#[get("{id}")] +pub async fn get_application_category( + state: web::Data, + id: web::Path, +) -> Result { + let id = id.into_inner(); + let res: Option = + ApplicationCategory::find_by_id(id).one(&state.db).await?; + match res { + Some(rec) => Ok(HttpResponse::Ok().json(rec)), + None => Err(Error::not_found()), + } +} + +#[instrument] +#[put("{id}")] +pub async fn update_application_category( + state: web::Data, + + data: web::Json, + id: web::Path, +) -> Result { + let id = id.into_inner(); + let res: Option = + ApplicationCategory::find_by_id(id).one(&state.db).await?; + match res { + Some(_rec) => { + let data = data.into_inner(); + let ret = application_category::ActiveModel { + id: Set(id), + active: Set(data.active), + category_name: Set(data.category_name), + }; + let model = ret.update(&state.db).await?; + Ok(HttpResponse::Ok().json(model)) + } + None => Err(Error::not_found()), + } +} + +#[instrument] +#[delete("{id}")] +pub async fn delete_application_category( + state: web::Data, + id: web::Path, +) -> Result { + ApplicationCategory::delete_many() + .filter(application_category::Column::Id.eq(id.into_inner())) + .exec(&state.db) + .await?; + + Ok(HttpResponse::Ok().body("")) +} + +#[instrument] +#[get("{id}/applications")] +pub async fn application_category_applications( + state: web::Data, + id: web::Path, +) -> Result { + let recs: Vec = Application::find() + .filter(application::Column::ApplicationCategoryId.eq(id.into_inner())) + .all(&state.db) + .await + .unwrap(); + + let count = recs.len(); + Ok(HttpResponse::Ok().json(ListObjects::new(recs, count))) +} + +/// Routes for the application endpoints. This binds up a scope with all endpoints for applications, to make it easier to add them to the server. +pub fn routes() -> Scope { + web::scope("/application_categories") + .service(application_category_applications) + .service(list_application_categories) + .service(update_application_category) + .service(delete_application_category) + .service(new_application_category) + .service(get_application_category) +} + +#[cfg(test)] +mod tests { + + use crate::api::test_prelude::*; + use actix_web::http::Method; + + #[actix_rt::test] + async fn test_list_application_categories() -> Result<()> { + let state = setup_state().await?; + application_category::ActiveModel { + category_name: Set("Application 1".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + application_category::ActiveModel { + category_name: Set("Application 2".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri("/application_categories") + .method(Method::GET) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let data = get_response!( + resp, + ListObjects + ); + assert_eq!(2_usize, data.items.len()); + Ok(()) + } + + #[actix_rt::test] + async fn test_get_application_categories() -> Result<()> { + let state = setup_state().await?; + let model = application_category::ActiveModel { + category_name: Set("Application 1".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri(&format!( + "/application_categories/{}", + model.id + )) + .method(Method::GET) + .to_request(); + let resp = call_endpoint!(req, state); + let status = resp.status(); + let mut data = get_response!(resp, crate::entity::application_category::Model); + data.id = model.id; + assert_eq!(model, data); + assert_eq!(status, 200); + Ok(()) + } + + #[actix_rt::test] + async fn test_new_application_category() -> Result<()> { + let model = application_category::Model { + id: 0, + category_name: "Some name".into(), + active: true, + }; + + let state = setup_state().await?; + + let req = actix_web::test::TestRequest::with_uri("/application_categories") + .method(Method::POST) + .set_json(model.clone()) + .to_request(); + + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let data = get_response!(resp, crate::entity::application_category::Model); + assert_eq!(model, data); + assert_eq!( + application_category::Entity::find() + .count(&state.db) + .await?, + 1 + ); + Ok(()) + } + + #[actix_rt::test] + async fn test_update_application_category() -> Result<()> { + let state = setup_state().await?; + application_category::ActiveModel { + category_name: Set("Some name".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let mut model = application_category::ActiveModel { + category_name: Set("Some name".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + model.category_name = "Another name".into(); + + let req = actix_web::test::TestRequest::with_uri(&format!( + "/application_categories/{}", + model.id + )) + .method(Method::PUT) + .set_json(model.clone()) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let mut data = get_response!(resp, crate::entity::application_category::Model); + data.id = model.id; + assert_eq!(model, data, "Check API"); + + let db_model = application_category::Entity::find_by_id(model.id) + .one(&state.db) + .await? + .unwrap(); + + assert_eq!(db_model, model, "Check DB"); + + Ok(()) + } + + #[actix_rt::test] + async fn test_delete_application_category() -> Result<()> { + let state = setup_state().await?; + let model = application_category::ActiveModel { + category_name: Set("Some name".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri(&format!( + "/application_categories/{}", + model.id + )) + .method(Method::DELETE) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + assert_eq!( + application_category::Entity::find() + .count(&state.db) + .await?, + 0 + ); + Ok(()) + } + + #[actix_rt::test] + async fn test_application_categories_applications() -> Result<()> { + let state = setup_state().await?; + let category = application_category::ActiveModel { + category_name: Set("Application 1".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + application::ActiveModel { + app_name: Set("Application 1".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + application_category_id: Set(Some(category.id)), + ..Default::default() + } + .insert(&state.db) + .await?; + application::ActiveModel { + app_name: Set("Application 2".into()), + url: Set("http://somewhere/".into()), + application_category_id: Set(Some(category.id)), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + application::ActiveModel { + app_name: Set("Application 2".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri(&format!( + "/application_categories/{}/applications", + category.id + )) + .method(Method::GET) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let data = get_response!(resp, ListObjects); + assert_eq!(2_usize, data.items.len()); + Ok(()) + } +} diff --git a/src/api/applications.rs b/src/api/applications.rs index 79392d4..d43904e 100644 --- a/src/api/applications.rs +++ b/src/api/applications.rs @@ -1,33 +1,250 @@ use tracing::instrument; use crate::api::api_prelude::*; +use crate::error::{Error, Result}; #[instrument] -#[get("/applications")] -pub async fn list_applications(state: web::Data) -> Result { +#[get("")] +pub async fn list_applications(state: web::Data) -> Result { let apps: Vec = Application::find().all(&state.db).await.unwrap(); - Ok(HttpResponse::Ok().json(apps)) + let count = apps.len(); + Ok(HttpResponse::Ok().json(ListObjects::new(apps, count))) +} + +#[instrument] +#[post("")] +pub async fn new_application( + state: web::Data, + data: web::Json, +) -> Result { + let model = application::ActiveModel { + id: NotSet, + app_name: Set(data.0.app_name), + description: Set(data.0.description), + url: Set(data.0.url), + active: Set(data.0.active), + glyph: Set(data.0.glyph), + application_category_id: Set(data.0.application_category_id), + }; + let app = model.insert(&state.db).await?; + Ok(HttpResponse::Ok().json(app)) +} + +#[instrument] +#[get("{id}")] +pub async fn get_applications( + state: web::Data, + id: web::Path, +) -> Result { + let id = id.into_inner(); + let res: Option = Application::find_by_id(id).one(&state.db).await?; + match res { + Some(app) => Ok(HttpResponse::Ok().json(app)), + None => Err(Error::not_found()), + } +} + +#[instrument] +#[put("{id}")] +pub async fn update_applications( + state: web::Data, + + data: web::Json, + id: web::Path, +) -> Result { + let id = id.into_inner(); + let res: Option = Application::find_by_id(id).one(&state.db).await?; + match res { + Some(_app) => { + let data = data.into_inner(); + let ret = application::ActiveModel { + id: Set(id), + active: Set(data.active), + app_name: Set(data.app_name), + description: Set(data.description), + url: Set(data.url), + application_category_id: Set(data.application_category_id), + glyph: Set(data.glyph), + }; + let model = ret.update(&state.db).await?; + Ok(HttpResponse::Ok().json(model)) + } + None => Err(Error::not_found()), + } +} + +#[instrument] +#[delete("{id}")] +pub async fn delete_application( + state: web::Data, + id: web::Path, +) -> Result { + Application::delete_many() + .filter(application::Column::Id.eq(id.into_inner())) + .exec(&state.db) + .await?; + + Ok(HttpResponse::Ok().body("")) +} + +/// Routes for the application endpoints. This binds up a scope with all endpoints for applications, to make it easier to add them to the server. +pub fn routes() -> Scope { + web::scope("/applications") + .service(list_applications) + .service(update_applications) + .service(delete_application) + .service(new_application) + .service(get_applications) } #[cfg(test)] mod tests { + use crate::api::test_prelude::*; use actix_web::http::Method; #[actix_rt::test] - async fn test_list_applications() { - let db = MockDatabase::new(DatabaseBackend::Sqlite) - .append_query_results(vec![vec![application::Model { - id: 1, - app_name: "Application 1".into(), - ..Default::default() - }]]) - .into_connection(); + async fn test_list_applications() -> Result<()> { + let state = setup_state().await?; + application::ActiveModel { + app_name: Set("Application 1".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + application::ActiveModel { + app_name: Set("Application 2".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; let req = actix_web::test::TestRequest::with_uri("/applications") .method(Method::GET) .to_request(); - let resp = call_endpoint!(req, db); + let resp = call_endpoint!(req, state); assert_eq!(resp.status(), 200); + let data = get_response!(resp, ListObjects); + assert_eq!(2_usize, data.items.len()); + Ok(()) + } + + #[actix_rt::test] + async fn test_get_applications() -> Result<()> { + let state = setup_state().await?; + let model = application::ActiveModel { + app_name: Set("Application 1".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri(&format!("/applications/{}", model.id)) + .method(Method::GET) + .to_request(); + let resp = call_endpoint!(req, state); + let status = resp.status(); + let mut data = get_response!(resp, crate::entity::application::Model); + data.id = model.id; + assert_eq!(model, data); + assert_eq!(status, 200); + Ok(()) + } + + #[actix_rt::test] + async fn test_new_application() -> Result<()> { + let model = application::Model { + id: 0, + app_name: "Application 1".into(), + glyph: Some("web".into()), + url: "http://example.com".into(), + description: Some("Some Application".into()), + active: true, + application_category_id: None, + }; + + let state = setup_state().await?; + + let req = actix_web::test::TestRequest::with_uri("/applications") + .method(Method::POST) + .set_json(model.clone()) + .to_request(); + + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let data = get_response!(resp, crate::entity::application::Model); + assert_eq!(model, data); + assert_eq!(application::Entity::find().count(&state.db).await?, 1); + Ok(()) + } + + #[actix_rt::test] + async fn test_update_application() -> Result<()> { + let state = setup_state().await?; + application::ActiveModel { + app_name: Set("Application 1".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let mut model = application::ActiveModel { + app_name: Set("Application 2".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + model.url = "http://updated.com".into(); + + let req = actix_web::test::TestRequest::with_uri(&format!("/applications/{}", model.id)) + .method(Method::PUT) + .set_json(model.clone()) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + let mut data = get_response!(resp, crate::entity::application::Model); + data.id = model.id; + assert_eq!(model, data, "Check API"); + + let db_model = application::Entity::find_by_id(model.id) + .one(&state.db) + .await? + .unwrap(); + + assert_eq!(db_model, model, "Check DB"); + + Ok(()) + } + + #[actix_rt::test] + async fn test_delete_application() -> Result<()> { + let state = setup_state().await?; + let model = application::ActiveModel { + app_name: Set("Application 1".into()), + url: Set("http://somewhere/".into()), + active: Set(true), + ..Default::default() + } + .insert(&state.db) + .await?; + + let req = actix_web::test::TestRequest::with_uri(&format!("/applications/{}", model.id)) + .method(Method::DELETE) + .to_request(); + let resp = call_endpoint!(req, state); + assert_eq!(resp.status(), 200); + assert_eq!(application::Entity::find().count(&state.db).await?, 0); + Ok(()) } } diff --git a/src/api/mod.rs b/src/api/mod.rs index 46f6173..5e2f9a9 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,35 +1,100 @@ -#[cfg(test)] +use serde::{Deserialize, Serialize}; + #[macro_export] +#[cfg(test)] macro_rules! call_endpoint { - ($req:ident, $db:ident) => {{ - let state = AppState { db: $db }; + ($req:ident, $state:ident) => {{ + // let subscriber = tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt::with( + // tracing_subscriber::registry(), + // tracing_subscriber::Layer::with_filter( + // tracing_subscriber::fmt::Layer::new() + // .pretty() + // .with_writer(std::io::stdout) + // .with_ansi(true), + // tracing_subscriber::filter::LevelFilter::DEBUG, + // ), + // ); + // tracing::subscriber::set_global_default(subscriber) + // .expect("Unable to set a global collector"); + let a = App::new() - .app_data(state) - .service(crate::api::applications::list_applications); - let mut app = actix_web::test::init_service(a).await; - let resp = actix_web::test::call_service(&mut app, $req).await; + .wrap(tracing_actix_web::TracingLogger::default()) + .app_data($state.clone()) + .service(crate::api::applications::routes()) + .service(crate::api::application_category::routes()); + let app = actix_web::test::init_service(a).await; + let resp = actix_web::test::call_service(&app, $req).await; resp }}; } +#[cfg(test)] +macro_rules! get_response { + ($resp: ident, $type:ty) => {{ + let body = test::read_body($resp).await.to_vec(); + serde_json::from_slice::<$type>(&body).unwrap() + }}; +} + +pub mod application_category; pub mod applications; mod api_prelude { + pub use super::ListObjects; pub use crate::entity::prelude::*; pub use crate::entity::*; pub use crate::AppState; - pub use actix_web::{get, web, Error, HttpResponse}; + pub use actix_web::{delete, get, post, put, web, Error, HttpResponse, Scope}; pub use sea_orm::prelude::*; + pub use sea_orm::{NotSet, Set}; } #[cfg(test)] mod test_prelude { + pub use super::ListObjects; pub use crate::entity::*; pub use crate::AppState; + pub use crate::error::Result; pub use actix_web::dev::ServiceResponse; pub use actix_web::{test, web, App}; + use sea_orm::sea_query::TableCreateStatement; + use sea_orm::ConnectionTrait; + use sea_orm::Database; + use sea_orm::DbBackend; + use sea_orm::Schema; pub use sea_orm::{ - entity::prelude::*, entity::*, tests_cfg::*, DatabaseBackend, MockDatabase, Transaction, + entity::prelude::*, entity::*, tests_cfg::*, DatabaseBackend, MockDatabase, MockExecResult, + Transaction, }; + + /// Sets up a testing state with an in-memory database and creates the scheme. + pub async fn setup_state() -> Result> { + let db = Database::connect("sqlite::memory:").await?; + let schema = Schema::new(DbBackend::Sqlite); + + let stmt: TableCreateStatement = schema.create_table_from_entity(application::Entity); + db.execute(db.get_database_backend().build(&stmt)).await?; + let stmt: TableCreateStatement = + schema.create_table_from_entity(application_category::Entity); + db.execute(db.get_database_backend().build(&stmt)).await?; + + Ok(actix_web::web::Data::new(AppState { db })) + } +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ListObjects +where + T: Serialize, +{ + items: Vec, + total: usize, +} + +impl ListObjects { + pub fn new(items: Vec, total: usize) -> Self { + Self { items, total } + } } diff --git a/src/entity/application.rs b/src/entity/application.rs index 2eba96e..38a4e07 100644 --- a/src/entity/application.rs +++ b/src/entity/application.rs @@ -5,8 +5,10 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)] #[sea_orm(table_name = "application")] +#[serde(rename_all = "camelCase")] pub struct Model { #[sea_orm(primary_key)] + #[serde(skip_deserializing)] pub id: i32, pub app_name: String, pub url: String, @@ -16,16 +18,27 @@ pub struct Model { pub application_category_id: Option, } -#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +#[derive(Copy, Clone, Debug, EnumIter)] pub enum Relation { - #[sea_orm( - belongs_to = "super::application_category::Entity", - from = "Column::ApplicationCategoryId", - to = "super::application_category::Column::Id" - )] ApplicationCategory, } +impl RelationTrait for Relation { + fn def(&self) -> RelationDef { + match self { + Self::ApplicationCategory => Entity::belongs_to(super::application_category::Entity) + .from(Column::ApplicationCategoryId) + .to(super::application_category::Column::Id) + .into(), + } + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ApplicationCategory.def() + } +} impl ActiveModelBehavior for ActiveModel {} #[cfg(test)] diff --git a/src/entity/application_category.rs b/src/entity/application_category.rs index f1c730b..a009d05 100644 --- a/src/entity/application_category.rs +++ b/src/entity/application_category.rs @@ -5,20 +5,31 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, Deserialize)] #[sea_orm(table_name = "application_category")] +#[serde(rename_all = "camelCase")] pub struct Model { #[sea_orm(primary_key)] + #[serde(skip_deserializing)] pub id: i32, pub category_name: String, pub active: bool, } #[derive(Copy, Clone, Debug, EnumIter)] -pub enum Relation {} +pub enum Relation { + Application, +} impl RelationTrait for Relation { fn def(&self) -> RelationDef { - panic!("No RelationDef") + match self { + Self::Application => Entity::has_many(super::application::Entity).into(), + } } } +impl Related for Entity { + fn to() -> RelationDef { + Relation::Application.def() + } +} impl ActiveModelBehavior for ActiveModel {} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..de78916 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,52 @@ +use serde::{Deserialize, Serialize}; + +pub type Result = std::result::Result; + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum ErrorCode { + NotFound, + DatabaseError, + Internal, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct Error { + code: ErrorCode, + message: String, +} + +impl Error { + pub fn not_found() -> Self { + Self { + code: ErrorCode::NotFound, + message: "Resource not found".to_string(), + } + } +} + +impl From<&str> for Error { + fn from(s: &str) -> Self { + Error { + code: ErrorCode::Internal, + message: s.into(), + } + } +} + +impl actix_web::error::ResponseError for Error {} + +impl From for Error { + fn from(e: sea_orm::DbErr) -> Self { + Self { + code: ErrorCode::DatabaseError, + message: e.to_string(), + } + } +} + +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message) + } +} diff --git a/src/main.rs b/src/main.rs index 7bb22ac..bc8221a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,11 @@ -use std::sync::Arc; - -use actix_web::{App, HttpServer}; +use actix_web::{web, App, HttpServer}; use sea_orm::{Database, DatabaseConnection}; -use tracing::{instrument, info}; +use tracing::{info, instrument}; use tracing_subscriber::prelude::*; mod api; - mod entity; +mod error; #[derive(Debug)] pub struct AppState { @@ -26,13 +24,14 @@ async fn main() { tracing::subscriber::set_global_default(subscriber).expect("Unable to set a global collector"); let db = setup_database().await.unwrap(); - let state = Arc::new(AppState { db }); + let state = web::Data::new(AppState { db }); info!("Starting http server on 8080"); HttpServer::new(move || { App::new() .app_data(state.clone()) - .service(api::applications::list_applications) + .service(api::applications::routes()) + .service(api::application_category::routes()) }) .bind("127.0.0.1:8080") .unwrap()