diff --git a/Cargo.lock b/Cargo.lock index 81d587d..d2e27ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -83,7 +83,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -110,6 +110,19 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.68" @@ -147,74 +160,11 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "axum" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" -dependencies = [ - "async-trait", - "axum-core", - "axum-macros", - "bitflags", - "bytes", - "futures-util", - "headers", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-macros" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb524613be645939e280b7279f7b017f98cf7f5ef084ec374df373530e73277" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bitflags" @@ -222,6 +172,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + [[package]] name = "bitvec" version = "1.0.1" @@ -250,7 +206,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ "borsh-derive", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -288,6 +244,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "regex-automata 0.4.5", + "serde", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -364,7 +331,7 @@ dependencies = [ "js-sys", "num-traits", "serde", - "time", + "time 0.1.45", "wasm-bindgen", "winapi", ] @@ -388,7 +355,7 @@ checksum = "9a78fbdd3cc2914ddf37ba444114bc7765bbdcb55ec9cbe6fa054f0137400717" dependencies = [ "anstream", "anstyle", - "bitflags", + "bitflags 1.3.2", "clap_lex", "strsim", ] @@ -417,6 +384,32 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +dependencies = [ + "percent-encoding", + "time 0.3.26", + "version_check", +] + [[package]] name = "cookie-factory" version = "0.3.2" @@ -450,6 +443,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -460,6 +459,63 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.18", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "serde", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -482,6 +538,15 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_logger" version = "0.7.1" @@ -496,24 +561,40 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "event-listener" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "b7ad6fd685ce13acd6d9541a30f6db6567a7a24c9ffd4ba2955d29e3f22c8b27" dependencies = [ - "cc", - "libc", + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener", + "pin-project-lite", ] [[package]] @@ -646,6 +727,12 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.28" @@ -664,6 +751,28 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -685,25 +794,6 @@ dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] -[[package]] -name = "h2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "hash32" version = "0.2.1" @@ -723,29 +813,10 @@ dependencies = [ ] [[package]] -name = "headers" -version = "0.3.8" +name = "hashbrown" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" -dependencies = [ - "base64", - "bitflags", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heapless" @@ -811,26 +882,15 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" dependencies = [ "bytes", "fnv", "itoa", ] -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - [[package]] name = "httparse" version = "1.8.0" @@ -852,30 +912,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "hyper" -version = "0.14.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -899,6 +935,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.4.0" @@ -916,7 +958,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", ] [[package]] @@ -927,7 +981,7 @@ checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -938,8 +992,8 @@ checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix", - "windows-sys", + "rustix 0.37.20", + "windows-sys 0.48.0", ] [[package]] @@ -1006,9 +1060,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -1022,6 +1076,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + [[package]] name = "lock_api" version = "0.4.10" @@ -1039,16 +1099,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] -name = "matchit" -version = "0.7.0" +name = "loom" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "pin-utils", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "mime" @@ -1070,18 +1147,25 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" + [[package]] name = "narodmon-server" version = "0.1.0" dependencies = [ "anyhow", - "axum", + "bstr", "bytes", "chrono", "clap", + "derive_more", "dotenvy", "fred", "heapless", @@ -1089,11 +1173,14 @@ dependencies = [ "hifitime", "lazy_static", "nom", + "ntex", "phf", "regex", "rust_decimal", "serde", "serde_json", + "serde_qs", + "serde_with", "smallstr", "thiserror", "tokio", @@ -1110,6 +1197,241 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459affa3ce5e34ad01588f6bb090a13a334de1633d228653abe662af6b8bf21b" +dependencies = [ + "async-channel", + "base64", + "bitflags 2.4.2", + "cookie", + "encoding_rs", + "httparse", + "httpdate", + "log", + "mime", + "nanorand", + "ntex-bytes", + "ntex-codec", + "ntex-connect", + "ntex-h2", + "ntex-http", + "ntex-io", + "ntex-macros", + "ntex-router", + "ntex-rt", + "ntex-service", + "ntex-tls", + "ntex-tokio", + "ntex-util", + "oneshot", + "percent-encoding", + "pin-project-lite", + "polling", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1", + "socket2 0.5.6", + "thiserror", + "url", +] + +[[package]] +name = "ntex-bytes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb17fec7b1e5f1b504a7f2f02a05ccfe7ad9ecb47fa039a0d7f5a55ff940dfa" +dependencies = [ + "bitflags 2.4.2", + "bytes", + "futures-core", + "serde", +] + +[[package]] +name = "ntex-codec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69a7e111d946bb915d712df496728ca2a120b1b5643f66c580f13023bce46fda" +dependencies = [ + "ntex-bytes", +] + +[[package]] +name = "ntex-connect" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a95f2470cb20e347c1a46ce647e16a0c896661f4ae09927a861447f828e674bc" +dependencies = [ + "log", + "ntex-bytes", + "ntex-http", + "ntex-io", + "ntex-rt", + "ntex-service", + "ntex-tls", + "ntex-tokio", + "ntex-util", + "thiserror", +] + +[[package]] +name = "ntex-h2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d7eee598e3b94175cef2f8c3818b61460307be543f2d9132aac36ac8d78f3d5" +dependencies = [ + "bitflags 2.4.2", + "fxhash", + "log", + "nanorand", + "ntex-bytes", + "ntex-codec", + "ntex-connect", + "ntex-http", + "ntex-io", + "ntex-rt", + "ntex-service", + "ntex-util", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "ntex-http" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81e205c980c693cb426f55669078bc311973f7e27a34f7ea4d0ce4069dedd05" +dependencies = [ + "fxhash", + "http", + "itoa", + "log", + "ntex-bytes", + "serde", +] + +[[package]] +name = "ntex-io" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae09b6d287fb72d50804cac045fba24a9d871bb59472bd20321d18c6525141b" +dependencies = [ + "bitflags 2.4.2", + "log", + "ntex-bytes", + "ntex-codec", + "ntex-service", + "ntex-util", + "pin-project-lite", +] + +[[package]] +name = "ntex-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50a359f2a10c712b0446675070c22b1437d57a7cf08139f6a229e1e80817ed84" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ntex-router" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9c68c26a87ffca54339be5f95223339db3e7bcc5d64733fef20812970a746f" +dependencies = [ + "http", + "log", + "ntex-bytes", + "regex", + "serde", +] + +[[package]] +name = "ntex-rt" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0302b642268700f5ac5233d6e2c547f5053efc8807bdc797c1acbad55996e0fb" +dependencies = [ + "async-channel", + "futures-core", + "log", + "oneshot", + "tokio", +] + +[[package]] +name = "ntex-service" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b4c979fdb3ce8ff5e7538fbdb60edfd960c6a9152456b9b6a22fcf4e830b254" +dependencies = [ + "slab", +] + +[[package]] +name = "ntex-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00fc944fdd939dcd8729ae6640efa079737bd6d421d71198ef23299bf8e38c47" +dependencies = [ + "log", + "ntex-bytes", + "ntex-io", + "ntex-service", + "ntex-util", + "pin-project-lite", +] + +[[package]] +name = "ntex-tokio" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd222124711e39aac5902abf45edbb385c2152d47230da41f5e5aed448795ed4" +dependencies = [ + "log", + "ntex-bytes", + "ntex-io", + "ntex-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "ntex-util" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caad794a6eb4d73fb4c13b7874fe3e6e9042deab50d6d325b584436efd0db433" +dependencies = [ + "bitflags 2.4.2", + "futures-core", + "futures-sink", + "futures-timer", + "fxhash", + "log", + "ntex-rt", + "ntex-service", + "pin-project-lite", + "slab", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -1136,6 +1458,27 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "oneshot" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6640c6bda7731b1fdbab747981a0f896dd1fedaf9f4a53fa237a04a84431f4" +dependencies = [ + "loom", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1156,7 +1499,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -1208,31 +1551,11 @@ dependencies = [ "siphasher", ] -[[package]] -name = "pin-project" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1240,6 +1563,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "polling" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24f040dee2588b4963afb4e420540439d126f73fdacf4a9c486a96d840bac3c9" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.31", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1365,25 +1702,52 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", ] [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rend" @@ -1402,7 +1766,7 @@ checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ "bitvec", "bytecheck", - "hashbrown", + "hashbrown 0.12.3", "ptr_meta", "rend", "rkyv_derive", @@ -1455,12 +1819,25 @@ version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] @@ -1475,6 +1852,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.1.0" @@ -1525,12 +1908,14 @@ dependencies = [ ] [[package]] -name = "serde_path_to_error" -version = "0.1.11" +name = "serde_qs" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" dependencies = [ + "percent-encoding", "serde", + "thiserror", ] [[package]] @@ -1545,6 +1930,36 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.2.3", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time 0.3.26", +] + +[[package]] +name = "serde_with_macros" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865f9743393e638991566a8b7a479043c2c8da94a33e0a31f18214c9cae0a64d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "sha-1" version = "0.10.1" @@ -1557,14 +1972,12 @@ dependencies = [ ] [[package]] -name = "sha1" -version = "0.10.5" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "lazy_static", ] [[package]] @@ -1623,6 +2036,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "spin" version = "0.9.8" @@ -1672,12 +2095,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "tap" version = "1.0.1" @@ -1713,6 +2130,16 @@ dependencies = [ "syn 2.0.18", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "time" version = "0.1.45" @@ -1724,6 +2151,34 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a79d09ac6b08c1ab3906a2f7cc2e81a0e27c7ae89c63812df75e52bef0751e07" +dependencies = [ + "deranged", + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c65469ed6b3a4809d987a41eb1dc918e9bc1d92211cbad7ae82931846f7451" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -1753,9 +2208,9 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.4.9", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1803,34 +2258,6 @@ dependencies = [ "serde", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.37" @@ -1838,11 +2265,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + [[package]] name = "tracing-core" version = "0.1.31" @@ -1850,13 +2288,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", + "valuable", ] [[package]] -name = "try-lock" -version = "0.2.4" +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] [[package]] name = "typenum" @@ -1935,21 +2397,18 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -2053,7 +2512,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -2062,7 +2521,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.3", ] [[package]] @@ -2071,13 +2539,28 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +dependencies = [ + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", ] [[package]] @@ -2086,42 +2569,84 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" + [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" + [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 9a3341f..a909712 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,11 @@ edition = "2021" [dependencies] anyhow = "1.0.71" -axum = { version = "0.6.18", features = ["http2", "headers", "macros"] } +bstr = { version = "1.9.0", features = ["serde"] } bytes = { version = "1.4.0", features = ["serde"] } chrono = { version = "0.4.26", features = ["serde"] } clap = { version = "4.3.8", features = ["derive", "env"] } +derive_more = "0.99.17" dotenvy = "0.15.7" fred = { version = "6.3.0", features = ["nom"] } heapless = { version = "0.7.16", features = ["ufmt-impl"] } @@ -18,11 +19,14 @@ hex = { version = "0.4.3", default-features = false } hifitime = "3.8.2" lazy_static = "1.4.0" nom = { version = "7.1.3", default-features = false, features = ["std", "alloc"] } +ntex = { version = "1.1.0", features = ["tokio", "cookie", "url"] } phf = { version = "0.11.2", features = ["serde", "macros"] } regex = "1.8.4" rust_decimal = { version = "1.30.0", features = ["rkyv", "rkyv-safe"] } serde = { version = "1.0.164", features = ["derive", "alloc"] } serde_json = "1.0.99" +serde_qs = "0.12.0" +serde_with = { version = "3.6.1", features = ["hex"] } smallstr = { version = "0.3.0", features = ["std", "union"] } thiserror = "1.0.40" tokio = { version = "1.28.2", features = ["full"] } diff --git a/src/hashes.rs b/src/hashes.rs index b664c27..77fdb8c 100644 --- a/src/hashes.rs +++ b/src/hashes.rs @@ -1,15 +1,15 @@ -use std::borrow::Cow; use phf::phf_map; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::borrow::Cow; -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] #[repr(u64)] pub enum SupportedUnit { - Celsius, // Needs verification > 273.15 - Percentage, // Needs verification >= 100 && <= 0 + Celsius, // Needs verification > 273.15 + Percentage, // Needs verification >= 100 && <= 0 MillimeterHg, // Needs verification - UVIndex, // Needs verification - Boolean, // Needs verification + UVIndex, // Needs verification + Boolean, // Needs verification and possible parsing Kbps, Volume, KWh, @@ -17,12 +17,13 @@ pub enum SupportedUnit { Volts, Watts, Seconds, + Hertz, } impl Serialize for SupportedUnit { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { serializer.serialize_str(match self { SupportedUnit::Celsius => "C", @@ -36,15 +37,16 @@ impl Serialize for SupportedUnit { SupportedUnit::Volts => "V", SupportedUnit::Watts => "W", SupportedUnit::Seconds => "s", - SupportedUnit::KWh => "KWh" + SupportedUnit::KWh => "KWh", + SupportedUnit::Hertz => "Hz", }) } } impl<'de> Deserialize<'de> for SupportedUnit { fn deserialize<'a, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let color_str = Cow::<'a, str>::deserialize(deserializer)?; match STR_TO_UNITS.get(color_str.as_ref()) { @@ -54,7 +56,6 @@ impl<'de> Deserialize<'de> for SupportedUnit { } } - static STR_TO_UNITS: phf::Map<&'static str, SupportedUnit> = phf_map! { "C" => SupportedUnit::Celsius, "%" => SupportedUnit::Percentage, diff --git a/src/ingest_protocol/error.rs b/src/ingest_protocol/error.rs index 037bb1a..80bb38a 100644 --- a/src/ingest_protocol/error.rs +++ b/src/ingest_protocol/error.rs @@ -1,19 +1,20 @@ -use std::fmt::{Display, Formatter}; -use std::num::ParseFloatError; +use bstr::BStr; use nom::error::VerboseError; +use std::fmt::{Debug, Display}; +use std::num::ParseFloatError; use thiserror::Error as ThisError; #[derive(Debug, ThisError)] -pub enum Error { - #[error("Oops it blew up")] +pub enum Error { + #[error("Nom error: {0}")] NomError(#[from] nom::Err>), - #[error("Oops it blew up")] + #[error("Failed to parse a timestamp")] TimestampParseError(ParseFloatError), - #[error("Oops it blew up")] + #[error("Unknown unit")] UnknownUnit(I), - #[error("Oops it blew up")] - DecimalParseError(#[from] rust_decimal::Error) -} \ No newline at end of file + #[error("Failed to parse a number")] + DecimalParseError(#[from] rust_decimal::Error), +} diff --git a/src/ingest_protocol/mod.rs b/src/ingest_protocol/mod.rs index 2ec627c..e05e262 100644 --- a/src/ingest_protocol/mod.rs +++ b/src/ingest_protocol/mod.rs @@ -1,5 +1,5 @@ -mod packet_types; pub mod error; +mod packet_types; pub mod parser; mod server; @@ -7,4 +7,3 @@ mod server; mod tests; pub use packet_types::*; - diff --git a/src/ingest_protocol/packet_types.rs b/src/ingest_protocol/packet_types.rs index 504a0d7..0d71dcb 100644 --- a/src/ingest_protocol/packet_types.rs +++ b/src/ingest_protocol/packet_types.rs @@ -1,42 +1,76 @@ +use crate::hashes::SupportedUnit; +use crate::ingest_protocol::error::Error; +use crate::ingest_protocol::parser::parse_mac_address; +use bstr::BStr; +use hifitime::Epoch; +use rust_decimal::Decimal; +use serde::{Deserialize, Serialize}; +use serde_with::formats::Separator; +use serde_with::serde_as; use std::borrow::Cow; use std::collections::HashSet; use std::hash::{Hash, Hasher}; -use hifitime::Epoch; -use rust_decimal::Decimal; -use crate::hashes::SupportedUnit; -#[derive(Debug, Clone)] -pub struct SensorValue<'a> { - pub mac: Cow<'a, str>, +#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct SensorValue { + pub mac: String, pub value: Decimal, pub time: Option, pub unit: Option, - pub name: Option>, + pub name: Option, } -impl<'a> Hash for SensorValue<'a> { +impl Hash for SensorValue { fn hash(&self, state: &mut H) { - self.mac.hash(state); + self.mac.hash(state) } } -impl<'a> PartialEq for SensorValue<'a> { - fn eq(&self, other: &Self) -> bool { - self.mac == other.mac +pub struct DashSeparator {} + +impl Separator for DashSeparator { + fn separator() -> &'static str { + "-" } } -impl<'a> Eq for SensorValue<'a> { - +fn mac_as_array(value: &str) -> Result<[u8; 6], Error<&str>> { + Ok(parse_mac_address(value)?.1) } -#[derive(Debug, Clone, Default)] -pub struct NarodMonPacket<'a> { +serde_with::serde_conv!( + MacAsArray, + [u8; 6], + |rgb: &[u8; 6]| rgb.to_owned(), + mac_as_array +); + +#[serde_as] +#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize)] +pub struct NMDeviceDataPacket { + #[serde(alias = "ID")] + #[serde_as(as = "MacAsArray")] pub mac: [u8; 6], - pub name: Option>, - pub values: HashSet>, - pub owner: Option>, + + pub name: Option, + + pub values: HashSet, + + pub owner: Option, + pub lat: Option, pub lon: Option, - pub alt: Option -} \ No newline at end of file + pub alt: Option, + + // HTTP GET/POST url-encode specific parameters + /// TODO: Желательное поведение в будущем: + /// - Если в values есть хотябы один times и этот time не None => Игнорируем этот time + /// - Если time нет у values => используем этот time (если он None, то соотв. считаем что информации о времени нет) + /// TODO: В базе всё должно храниться как секунды по TAI спустя J1900 для возможности сортировки по времени позже. + pub time: Option, +} + +#[derive(Debug, Clone, Default, PartialEq, Deserialize)] +pub struct NMJsonPacket { + pub devices: Vec, +} diff --git a/src/ingest_protocol/parser.rs b/src/ingest_protocol/parser.rs index c202a63..c71e8d7 100644 --- a/src/ingest_protocol/parser.rs +++ b/src/ingest_protocol/parser.rs @@ -1,56 +1,52 @@ -use std::borrow::Cow; -use std::collections::HashSet; -use std::str::FromStr; use hifitime::Epoch; -use nom::{InputTake, Needed, Parser}; -use nom::branch::alt; -use nom::bytes::complete::{take_until, take_until1, take_while_m_n}; -use nom::bytes::complete::{take_till1, take, take_while, take_while1}; use nom::bytes::complete::tag; -use nom::bytes::streaming::take_till; -use nom::character::streaming::{anychar, char, hex_digit0, newline}; +use nom::bytes::complete::take_until1; +use nom::bytes::complete::{take, take_while, take_while1}; use nom::character::complete::hex_digit1; -use nom::character::is_digit; +use nom::{InputTake, Parser}; +use std::str::FromStr; -use nom::combinator::{map, map_opt, map_parser, opt, recognize, rest}; -use nom::Err as NomErr; -use nom::error::{context, ContextError, ErrorKind as NomErrorKind, ParseError as NomParseError, Error as NomError, VerboseError}; -use nom::multi::{count, separated_list0, separated_list1}; -use nom::sequence::{delimited, preceded, separated_pair}; -use rust_decimal::Decimal; use crate::ingest_protocol::error::Error; -use crate::ingest_protocol::{NarodMonPacket, SensorValue}; use crate::ingest_protocol::error::Error::TimestampParseError; +use crate::ingest_protocol::{NMDeviceDataPacket, SensorValue}; +use nom::combinator::{map_parser, opt}; +use nom::error::context; +use nom::multi::{count, separated_list0}; +use nom::sequence::{delimited, preceded}; +use rust_decimal::Decimal; type MyIError = Result<(I, O), Error>; - pub fn parse_mac_address(input: &str) -> MyIError<&str, [u8; 6]> { let mut mac = [0u8; 6]; let mut counter = 0; - let (leftovers, i) = context("17 символов для MAC адреса", take(17usize))(input)?; + let (leftovers, i) = + context("17 символов для MAC адреса", take(17usize))(input)?; - let (_, out) = count(|inp| { - let (mut i, o) = context("Октет", map_parser(take(2usize), hex_digit1))(inp)?; - if counter != 5 { - (i, _) = tag("-")(i)?; - } - counter += 1; - Ok((i, o)) - }, 6)(i)?; + let (_, out) = count( + |inp| { + let (mut i, o) = context("Октет", map_parser(take(2usize), hex_digit1))(inp)?; + if counter != 5 { + (i, _) = tag("-")(i)?; + } + counter += 1; + Ok((i, o)) + }, + 6, + )(i)?; hex::decode_to_slice(out.join(""), &mut mac).unwrap(); Ok((leftovers, mac)) } -fn handle_special_sensor_macs ( - mac: &str, +fn handle_special_sensor_macs<'a>( + mac: &'a str, sensor_value: &str, - packet: &mut NarodMonPacket, -) -> Result> { + packet: &mut NMDeviceDataPacket, +) -> Result> { match mac.to_uppercase().as_str() { "LAT" => packet.lat = Some(Decimal::from_str(sensor_value)?), "LON" => packet.lon = Some(Decimal::from_str(sensor_value)?), @@ -62,7 +58,10 @@ fn handle_special_sensor_macs ( return Ok(true); } -pub fn parse_packet_body<'a>(line: &'a str, packet: &mut NarodMonPacket<'a>) -> MyIError<&'a str, ()> { +pub fn parse_packet_body<'a>( + line: &'a str, + packet: &mut NMDeviceDataPacket, +) -> MyIError<&'a str, ()> { let (line, _) = tag("#")(line)?; let (line, sensor_mac) = take_while1(|c| c != '\n' && c != '#')(line)?; @@ -79,17 +78,17 @@ pub fn parse_packet_body<'a>(line: &'a str, packet: &mut NarodMonPacket<'a>) -> } _ => { let (line, sensor_value) = take_while1(|c| c != '\n' && c != '#')(line)?; - let (line, sensor_time) = opt(preceded(tag("#"), take_while1(|c| c != '\n' && c != '#' && "1234567890.".contains(c))))(line)?; + let (line, sensor_time) = opt(preceded( + tag("#"), + take_while1(|c| c != '\n' && c != '#' && "1234567890.".contains(c)), + ))(line)?; let (line, sensor_name) = opt(preceded(tag("#"), take_while1(|c| c != '\n')))(line)?; - let sensor_time = match sensor_time { - Some(v) => Some( - Epoch::from_unix_seconds( - v.parse().map_err(|e| TimestampParseError(e))? - ) - ), - None => None + Some(v) => Some(Epoch::from_unix_seconds( + v.parse().map_err(|e| TimestampParseError(e))?, + )), + None => None, }; if !handle_special_sensor_macs(sensor_mac, sensor_value, packet)? { @@ -98,31 +97,31 @@ pub fn parse_packet_body<'a>(line: &'a str, packet: &mut NarodMonPacket<'a>) -> value: Decimal::from_str(sensor_value)?, time: sensor_time, // TODO unit: None, - name: sensor_name.map(|v| Cow::from(v)), + name: sensor_name.map(|v| v.to_string()), }); } } } - return Ok((line, ())) + return Ok((line, ())); } -pub fn parse_packet(input: &str) -> MyIError<&str, NarodMonPacket> { +pub fn parse_packet(input: &str) -> MyIError<&str, NMDeviceDataPacket> { let (input, _) = tag("#")(input)?; let (input, device_mac) = parse_mac_address(input)?; let (input, opt_name) = opt(delimited(tag("#"), take_while(|c| c != '\n'), tag("\n")))(input)?; - let mut packet = NarodMonPacket::default(); + let mut packet = NMDeviceDataPacket::default(); packet.mac = device_mac; let (input, lines) = context( "Получение значений до тега терминатора", map_parser( take_until1("##"), - separated_list0(tag("\n"), take_while1(|c| c != '\n')) - ) + separated_list0(tag("\n"), take_while1(|c| c != '\n')), + ), )(input)?; for line in lines { @@ -131,7 +130,7 @@ pub fn parse_packet(input: &str) -> MyIError<&str, NarodMonPacket> { let (input, _) = tag("##")(input)?; - packet.name = opt_name.map(|v| Cow::from(v)); + packet.name = opt_name.map(|v| v.to_string()); Ok((input, packet)) -} \ No newline at end of file +} diff --git a/src/ingest_protocol/server.rs b/src/ingest_protocol/server.rs index 1381fea..3b37cdd 100644 --- a/src/ingest_protocol/server.rs +++ b/src/ingest_protocol/server.rs @@ -1,3 +1 @@ -async fn main() { - -} \ No newline at end of file +async fn main() {} diff --git a/src/ingest_protocol/tests/mod.rs b/src/ingest_protocol/tests/mod.rs index 73ed710..12e5967 100644 --- a/src/ingest_protocol/tests/mod.rs +++ b/src/ingest_protocol/tests/mod.rs @@ -12,7 +12,8 @@ fn test_asd() { #LON#37.6068 #ALT#38 ## -"#.trim(); +"# + .trim(); dbg!(parse_packet(asd)); } @@ -32,6 +33,5 @@ fn test_packet() { #T2#1.2#3400005345 ##"#; - println!("{:#?}", parse_packet(inp)); -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 9ed99b9..c497e58 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,25 +37,23 @@ C названием и координатами: extern crate core; mod hashes; -mod web_server; mod ingest_protocol; +mod web_server; use std::borrow::Cow; use std::collections::{BTreeSet, HashMap, HashSet}; use std::mem::{size_of, size_of_val}; use std::num::NonZeroUsize; use std::str::FromStr; -use axum::Router; -use axum::routing::post; + use hifitime::Epoch; -use rust_decimal::Decimal; -use crate::ingest_protocol::{NarodMonPacket, SensorValue}; use crate::ingest_protocol::error::Error; use crate::ingest_protocol::error::Error::TimestampParseError; +use crate::ingest_protocol::{NMDeviceDataPacket, SensorValue}; use crate::web_server::old_app_api::old_api_handler; use crate::web_server::server_main; - +use rust_decimal::Decimal; /*fn parse_sensor_value(input: Vec<&str>) -> MyIError, NarodMonValues> { Ok( @@ -68,20 +66,14 @@ use crate::web_server::server_main; ) }*/ +struct Params {} -struct Params { - -} - - - -#[tokio::main] +#[ntex::main] async fn main() { //dotenvy::dotenv().unwrap(); - - let web_server_hndl = tokio::spawn(server_main()); - - web_server_hndl.await.unwrap(); + // + // let web_server_hndl = tokio::spawn(server_main()); + // + // web_server_hndl.await.unwrap(); + server_main().await; } - - diff --git a/src/web_server/app_error.rs b/src/web_server/app_error.rs index 4eb15e5..ee7b853 100644 --- a/src/web_server/app_error.rs +++ b/src/web_server/app_error.rs @@ -1,99 +1,135 @@ -use std::borrow::Cow; -use axum::headers::HeaderValue; -use axum::http::StatusCode; -use axum::Json; -use axum::response::{IntoResponse, Response}; +use derive_more::Display; use fred::prelude::*; +use ntex::http::header::{HeaderName, HeaderValue}; +use ntex::http::{HeaderMap, Response, StatusCode}; +use ntex::web; +use ntex::web::types::Json; +use ntex::web::{App, HttpRequest, HttpResponse}; +use std::borrow::Cow; +use std::fmt::format; +use std::str::FromStr; +use thiserror::Error; - +use crate::ingest_protocol::error::Error; +use crate::insert_header; +use crate::web_server::old_devices_api::QSParserError; use rust_decimal::Decimal; use serde_json::json; -use thiserror::Error; use ufmt::derive::uDebug; -#[derive(Debug, Error)] +#[derive(Debug, Error, Display)] pub enum AppError { - #[error("IDK")] + #[display(fmt = "IDK")] JsonError(#[from] serde_json::Error), - #[error("IDK")] + #[display(fmt = "IDK")] + QSError(QSParserError), + + #[display(fmt = "IDK")] ServerRedisError(#[from] RedisError), - #[error("Fuck")] + #[display(fmt = "IDK")] UnknownMethod(String), - #[error("Fuck")] + #[display(fmt = "IDK")] RequestTooLarge, - #[error("Api")] - ApiKeyInvalid { - reason: &'static str - }, + #[display(fmt = "IDK")] + ApiKeyInvalid { reason: &'static str }, - #[error("Fuck")] + #[display(fmt = "IDK")] UnitValidationFailed { max: Option, - min: Option - } + min: Option, + }, + + #[display(fmt = "IDK")] + UnknownBody { + json_err: Option, + query_error: Option, + }, } -impl IntoResponse for AppError { - fn into_response(self) -> Response { +impl web::error::WebResponseError for AppError { + fn status_code(&self) -> StatusCode { + match self { + AppError::JsonError(_) => StatusCode::BAD_REQUEST, + AppError::UnknownMethod(_) => StatusCode::BAD_REQUEST, + AppError::UnitValidationFailed { .. } => StatusCode::BAD_REQUEST, + AppError::RequestTooLarge => StatusCode::PAYLOAD_TOO_LARGE, + AppError::ServerRedisError(_) => StatusCode::INTERNAL_SERVER_ERROR, + AppError::ApiKeyInvalid { .. } => StatusCode::BAD_REQUEST, + AppError::UnknownBody { .. } => StatusCode::BAD_REQUEST, + AppError::QSError(..) => StatusCode::BAD_REQUEST, + } + } - - let (status, error_message) = match self { - AppError::JsonError(_) => { - (StatusCode::BAD_REQUEST, "Invalid JSON") - }, - AppError::UnknownMethod(_) => { - (StatusCode::BAD_REQUEST, "Unknown command") - }, - AppError::UnitValidationFailed { .. } => { - (StatusCode::BAD_REQUEST, "Unknown command") - }, - AppError::RequestTooLarge => { - (StatusCode::PAYLOAD_TOO_LARGE, "Request is too large") - }, - AppError::ServerRedisError(_) => { - (StatusCode::INTERNAL_SERVER_ERROR, "Internal server error") - }, - AppError::ApiKeyInvalid { .. } => { - (StatusCode::BAD_REQUEST, "API Key invalid") + fn error_response(&self, _: &HttpRequest) -> HttpResponse { + let error_message = match self { + AppError::JsonError(_) => "Invalid JSON", + AppError::UnknownMethod(_) => "Unknown command", + AppError::UnitValidationFailed { .. } => "Unknown command", + AppError::RequestTooLarge => "Request is too large", + AppError::ServerRedisError(_) => "Internal server error", + AppError::ApiKeyInvalid { .. } => "API Key invalid", + AppError::UnknownBody { .. } => { + "Can't figure out where and in what encoding the main data is" } + AppError::QSError(..) => "UrlEncoded body or query params are incorrect", }; - let body = Json(json!({ - "errno": status.as_u16(), - "error": error_message, - })); + let status_code = self.status_code(); - let mut resp = (status, body).into_response(); + let body = json!({ + "errno": status_code.as_u16(), + "error": error_message, + }); + + let mut resp = HttpResponse::build(status_code).json(&body); let headers = resp.headers_mut(); - let error_as_string= format!("{:?}", &self); + let error_as_string = format!("{:?}", &self); match self { AppError::JsonError(json_err) => { - headers.insert("X-Error-Line", HeaderValue::from(json_err.line())); - headers.insert("X-Error-Column", HeaderValue::from(json_err.column())); - headers.insert("X-Error-Description", HeaderValue::try_from(json_err.to_string().escape_default().collect::()).unwrap()); - }, + insert_header!(headers, "X-Error-Line", json_err.line()); + insert_header!(headers, "X-Error-Column", json_err.column()); + insert_header!( + headers, + "X-Error-Description", + json_err.to_string().escape_default().collect::() + ); + } AppError::UnknownMethod(method) => { - headers.insert("X-Unknown-Cmd", HeaderValue::try_from(method.escape_default().collect::()).unwrap()); - }, + insert_header!( + headers, + "X-Unknown-Cmd", + method.escape_default().collect::() + ); + } AppError::RequestTooLarge => { - headers.insert("X-Max-Request-Size", HeaderValue::try_from("10 KiB = 10240 bytes").unwrap()); - }, + insert_header!(headers, "X-Max-Request-Size", "10 KiB = 10240 bytes"); + } AppError::ApiKeyInvalid { reason } => { - headers.insert("X-Error-Description", HeaderValue::try_from(reason).unwrap()); + insert_header!(headers, "X-Error-Description", *reason); + } + AppError::QSError(err) => match err { + QSParserError::ParsingError(desc) => { + insert_header!( + headers, + "X-Error-Description", + desc.escape_default().to_string() + ); + } + _ => {} }, _ => {} }; if cfg!(debug_assertions) { - headers.insert("X-Full-Error", HeaderValue::try_from(error_as_string).unwrap()); + insert_header!(headers, "X-Full-Error", error_as_string); } resp } -} \ No newline at end of file +} diff --git a/src/web_server/mod.rs b/src/web_server/mod.rs index 5f35c6f..6f6eaa3 100644 --- a/src/web_server/mod.rs +++ b/src/web_server/mod.rs @@ -1,26 +1,22 @@ -use std::time::Duration; -use tokio; -use axum::{ - routing::get, - Router, -}; -use axum::error_handling::{HandleError, HandleErrorLayer}; -use axum::http::StatusCode; -use axum::routing::post; +use crate::web_server::old_app_api::old_api_handler; use fred::bytes_utils::Str; use fred::prelude::*; -use crate::web_server::old_app_api::old_api_handler; +use std::time::Duration; +use tokio; -pub mod old_app_api; -mod utils; pub(crate) mod app_error; +pub mod old_app_api; +mod old_devices_api; +pub mod utils; #[derive(Clone)] pub struct NMAppState { - pub redis_client: RedisClient + pub redis_client: RedisClient, } +use crate::web_server::old_devices_api::device_handler; use heapless::String as HeaplessString; +use ntex::web; pub async fn server_main() { let config = RedisConfig::default(); @@ -37,16 +33,19 @@ pub async fn server_main() { println!("Ping result: {}", asd); let state = NMAppState { - redis_client: client + redis_client: client, }; - let app = Router::new() - .route("/api", post(old_api_handler)) - .with_state(state); - - - axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) - .serve(app.into_make_service()) - .await - .unwrap(); + web::HttpServer::new(move || { + web::App::new() + .state(state.clone()) + .route("/api", web::post().to(old_api_handler)) + .route("/get", web::route().to(device_handler)) + .route("/post", web::route().to(device_handler)) + }) + .bind(("127.0.0.1", 8080)) + .unwrap() + .run() + .await + .unwrap(); // TODO figure out how to handle what } diff --git a/src/web_server/old_app_api/config_app.rs b/src/web_server/old_app_api/config_app.rs index 3c5c1db..4e01abb 100644 --- a/src/web_server/old_app_api/config_app.rs +++ b/src/web_server/old_app_api/config_app.rs @@ -1,41 +1,44 @@ use std::borrow::Cow; -use axum::body::{Body, Bytes, HttpBody}; -use axum::extract::State; -use axum::http::Request; -use axum::Json; -use axum::response::{IntoResponse, Response}; -use nom::AsBytes; -use serde_json::Value; + use crate::web_server::app_error::AppError; -use crate::web_server::NMAppState; -use crate::web_server::old_app_api::handlers::app_init; +use crate::web_server::old_app_api::handlers::{app_init, version}; use crate::web_server::old_app_api::types::{AppInitRequest, MandatoryParams}; use crate::web_server::utils::redis::is_api_key_valid; - +use crate::web_server::NMAppState; +use nom::AsBytes; +use ntex::util::Bytes; +use ntex::web; +use ntex::web::types::State; +use serde_json::Value; pub async fn old_api_handler( app_state: State, body_bytes: Bytes, -) -> Result { - if body_bytes.len() > 10 * 1024 { // 10 KiB - return Err(AppError::RequestTooLarge) +) -> Result { + if body_bytes.len() > 10 * 1024 { + // 10 KiB + return Err(AppError::RequestTooLarge); } - let mandatory_params: MandatoryParams<'_> = serde_json::from_slice(body_bytes.as_bytes())?; // TODO: Simd-JSON + let body_bytes = body_bytes.as_bytes(); + + let mandatory_params: MandatoryParams<'_> = serde_json::from_slice(body_bytes)?; // TODO: Simd-JSON + + match mandatory_params.cmd.as_ref() { + "version" => return Ok(version((), &app_state).await?), + _ => {} + } is_api_key_valid(&app_state.redis_client, mandatory_params.api_key.as_ref()).await?; - return match mandatory_params.cmd.as_ref() { + match mandatory_params.cmd.as_ref() { "appInit" => { - let body: AppInitRequest = serde_json::from_slice(body_bytes.as_bytes())?; + let body: AppInitRequest = serde_json::from_slice(body_bytes)?; - Ok(app_init(body, app_state).await) - } - _ => { - Err(AppError::UnknownMethod(mandatory_params.cmd.to_string())) + return Ok(app_init(body, &app_state).await?); } + _ => Err(AppError::UnknownMethod(mandatory_params.cmd.to_string())), } //Ok("fuck") } - diff --git a/src/web_server/old_app_api/handlers/methods.rs b/src/web_server/old_app_api/handlers/methods.rs index 600d642..7bf34a9 100644 --- a/src/web_server/old_app_api/handlers/methods.rs +++ b/src/web_server/old_app_api/handlers/methods.rs @@ -1,20 +1,36 @@ -use axum::body::Body; -use axum::extract::State; -use axum::http::{Request, StatusCode}; -use axum::Json; -use axum::response::IntoResponse; - -use serde_json::Value as JsonValue; -use crate::web_server::old_app_api::types::AppInitRequest; -use heapless::String as HeaplessString; -use ufmt::uwrite; -use crate::web_server::NMAppState; use crate::web_server::app_error::AppError; +use crate::web_server::old_app_api::types::AppInitRequest; +use crate::web_server::NMAppState; +use heapless::String as HeaplessString; +use serde_json::{json, Value as JsonValue}; +use ufmt::uwrite; +use crate::insert_header; use fred::interfaces::KeysInterface; +use ntex::http::StatusCode; +use ntex::web; +use ntex::web::types::State; +use ntex::web::Responder; -pub async fn app_init(body: AppInitRequest<'_>, State(appState): State) -> Result { - let _: () = appState.redis_client.set("test", 123, None, None, true).await?; +pub async fn app_init( + body: AppInitRequest<'_>, + app_state: &NMAppState, +) -> Result { + let _: () = app_state + .redis_client + .set("test", 123, None, None, true) + .await?; - Ok((StatusCode::OK, "Hello, World!").into_response()) -} \ No newline at end of file + Ok(web::HttpResponse::build(StatusCode::OK).body("Hello world!")) +} + +pub async fn version(body: (), app_state: &NMAppState) -> Result { + let mut resp = web::HttpResponse::build(StatusCode::OK).json(&json!({ + "version": "indev", + "iotishnik": true + })); + + insert_header!(resp.headers_mut(), "Cache-Control", "no-cache"); + + Ok(resp) +} diff --git a/src/web_server/old_app_api/handlers/mod.rs b/src/web_server/old_app_api/handlers/mod.rs index 56e461b..f784445 100644 --- a/src/web_server/old_app_api/handlers/mod.rs +++ b/src/web_server/old_app_api/handlers/mod.rs @@ -1,10 +1,7 @@ mod methods; -use std::collections::HashMap; -use axum::Json; -use axum::response::IntoResponse; -use phf::phf_map; -use serde::{Deserialize, Serialize}; use crate::hashes::SupportedUnit; pub use methods::*; - +use phf::phf_map; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; diff --git a/src/web_server/old_app_api/mod.rs b/src/web_server/old_app_api/mod.rs index 6aa4103..c1572dd 100644 --- a/src/web_server/old_app_api/mod.rs +++ b/src/web_server/old_app_api/mod.rs @@ -1,6 +1,5 @@ -mod types; -mod handlers; mod config_app; +mod handlers; +mod types; pub use config_app::old_api_handler; - diff --git a/src/web_server/old_app_api/types/mod.rs b/src/web_server/old_app_api/types/mod.rs index 2241015..774e05b 100644 --- a/src/web_server/old_app_api/types/mod.rs +++ b/src/web_server/old_app_api/types/mod.rs @@ -1,6 +1,6 @@ -use std::borrow::Cow; -use serde::{Deserialize, Deserializer, Serialize}; use crate::hashes::SupportedUnit; +use serde::{Deserialize, Deserializer, Serialize}; +use std::borrow::Cow; // fn<'de, D>(D) -> Result where D: Deserializer<'de> @@ -15,7 +15,7 @@ pub struct AppInitRequest<'a> { #[serde(borrow)] pub model: Cow<'a, str>, - pub width: u64 + pub width: u64, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -36,5 +36,5 @@ pub struct MandatoryParams<'a> { pub uuid: Cow<'a, str>, #[serde(borrow)] - pub api_key: Cow<'a, str> -} \ No newline at end of file + pub api_key: Cow<'a, str>, +} diff --git a/src/web_server/old_devices_api/mod.rs b/src/web_server/old_devices_api/mod.rs new file mode 100644 index 0000000..d03539d --- /dev/null +++ b/src/web_server/old_devices_api/mod.rs @@ -0,0 +1,109 @@ +use crate::ingest_protocol::error::Error; +use crate::ingest_protocol::parser::parse_mac_address; +use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket}; +use crate::web_server::app_error::AppError; +use bstr::BStr; +use ntex::http::error::DecodeError::Method; +use ntex::http::{HttpMessage, Payload, StatusCode}; +use ntex::util::{Bytes, HashMap}; +use ntex::{http, web}; +use std::sync::Arc; +use thiserror::Error; + +/// В иделае было бы хорошо сделать всё как у [serde_json::Error], но это слишком большая морока +#[derive(Error, Clone, Debug)] +pub enum QSParserError { + #[error("asd")] + SerdeQSError(#[from] Arc), + #[error("asd")] + ParsingError(String), + #[error("asd")] + NoMAC, +} + +impl From> for QSParserError { + fn from(value: Error<&str>) -> Self { + QSParserError::ParsingError(format!("{:?}", value)) + } +} + +impl From for QSParserError { + fn from(value: serde_qs::Error) -> Self { + QSParserError::SerdeQSError(Arc::new(value)) + } +} + +pub async fn parse_nm_qs_format<'a>(input: &'a str) -> Result { + let parsed: HashMap<&str, &str> = serde_qs::from_str(input)?; + + let (_, device_mac) = if let Some(id) = parsed.get("ID") { + parse_mac_address(*id)? + } else { + return Err(QSParserError::NoMAC); + }; + + let device_data = NMDeviceDataPacket { + mac: [0u8; 6], + name: None, + values: Default::default(), + owner: None, + lat: None, + lon: None, + alt: None, + time: None, + }; + + return Ok(device_data); +} + +pub async fn device_handler<'a>( + request: web::HttpRequest, + body: Bytes, +) -> Result { + let mut real_body: Option = None; + let mut json_error = None; + let mut query_error = None; + + dbg!(&request.content_type()); + dbg!(&request.query_string()); + + if request.method() == http::Method::POST { + match request.content_type() { + "application/json" => match serde_json::from_slice::(body.as_ref()) { + Ok(json_body) => real_body = Some(json_body), + Err(error) => json_error = Some(error), + }, + "application/x-www-form-urlencoded" => { + match serde_qs::from_bytes::(body.as_ref()) { + Ok(qs_body) => { + real_body = Some(NMJsonPacket { + devices: Vec::from([qs_body]), + }) + } + Err(error) => query_error = Some(error), + } + } + _ => {} + } + } else if request.method() == http::Method::GET { + match serde_qs::from_str::(request.query_string()) { + Ok(qs_body) => { + real_body = Some(NMJsonPacket { + devices: Vec::from([qs_body]), + }) + } + Err(error) => query_error = Some(error), + } + } + + if let Some(body) = real_body { + // TODO + } else { + return Err(AppError::UnknownBody { + json_err: json_error, + query_error: query_error, + }); + } + + Ok(web::HttpResponse::build(StatusCode::OK).finish()) +} diff --git a/src/web_server/utils/mod.rs b/src/web_server/utils/mod.rs index ac3a5c6..5fed630 100644 --- a/src/web_server/utils/mod.rs +++ b/src/web_server/utils/mod.rs @@ -1 +1,8 @@ -pub mod redis; \ No newline at end of file +pub mod redis; + +#[macro_export] +macro_rules! insert_header { + ($headers: expr, $name: expr, $value: expr) => { + $headers.insert($name.try_into().unwrap(), $value.try_into().unwrap()); + }; +} diff --git a/src/web_server/utils/redis.rs b/src/web_server/utils/redis.rs index abf426f..fe6a9da 100644 --- a/src/web_server/utils/redis.rs +++ b/src/web_server/utils/redis.rs @@ -1,31 +1,36 @@ +use crate::web_server::app_error::AppError; use fred::prelude::*; use heapless::String as HeaplessString; use lazy_static::lazy_static; use regex::Regex; use ufmt::uwrite; -use crate::web_server::app_error::AppError; lazy_static! { static ref ALLOWED_API_KEY_CHARACTERS: Regex = Regex::new("[a-zA-Z0-9]{13}").unwrap(); } pub struct ApiKeyDescription { - apikey_owner: i64 + apikey_owner: i64, } -pub async fn is_api_key_valid(client: &RedisClient, api_key: &str) -> Result { +pub async fn is_api_key_valid( + client: &RedisClient, + api_key: &str, +) -> Result { if !ALLOWED_API_KEY_CHARACTERS.is_match(api_key) { - return Err(AppError::ApiKeyInvalid { reason: "Invalid characters present in the API key." }) + return Err(AppError::ApiKeyInvalid { + reason: "Invalid characters present in the API key.", + }); } - let mut key_buffer = HeaplessString::<{7 + 13}>::new(); - uwrite!(key_buffer, "apikey_{}", api_key); + let mut key_buffer = HeaplessString::<{ 7 + 13 }>::new(); + uwrite!(key_buffer, "apikey_{}", api_key).expect("TODO"); // TODO: Error handling let valid: Option = client.hget(key_buffer.as_str(), "owner").await?; - valid.map(|uid| { - ApiKeyDescription { - apikey_owner: uid - } - }).ok_or(AppError::ApiKeyInvalid { reason: "Unknown API key" }) -} \ No newline at end of file + valid + .map(|uid| ApiKeyDescription { apikey_owner: uid }) + .ok_or(AppError::ApiKeyInvalid { + reason: "Unknown API key", + }) +}