diff --git a/Cargo.lock b/Cargo.lock index 80552d9..b01cf4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,20 +72,15 @@ dependencies = [ [[package]] name = "anwesen" -version = "0.4.0" +version = "0.1.0" dependencies = [ "anyhow", "axum", "blake3", "chrono", "clap", - "http-body", "hydra", "notify", - "opentelemetry", - "opentelemetry-otlp", - "opentelemetry-semantic-conventions", - "opentelemetry_sdk", "regex", "serde", "serde_json", @@ -127,17 +122,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "async-trait" -version = "0.1.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae36dc4177970ef04fde5178d3e2429882def40e57a451f919c098f72baa6cec" -dependencies = [ - "proc-macro2", - "quote", - "syn 3.0.3", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -150,29 +134,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" -[[package]] -name = "aws-lc-rs" -version = "1.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bdb5da18dac48ca2cc7cd4a98e533e8635a58e2361d13a1a4ee3888e0d72f1" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.43.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43103168cc76fe62678a375e722fc9cb3a0146159ac5828bc4f0dfd755c2224c" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", - "pkg-config", -] - [[package]] name = "axum" version = "0.8.9" @@ -225,12 +186,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bincode" version = "2.0.1" @@ -299,8 +254,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", - "jobserver", - "libc", "shlex", ] @@ -310,23 +263,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cfg_aliases" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" - -[[package]] -name = "chacha20" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" -dependencies = [ - "cfg-if", - "cpufeatures 0.3.0", - "rand_core 0.10.1", -] - [[package]] name = "chrono" version = "0.4.44" @@ -370,7 +306,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -379,47 +315,18 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" -[[package]] -name = "cmake" -version = "0.1.58" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" -dependencies = [ - "cc", -] - [[package]] name = "colorchoice" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - [[package]] name = "constant_time_eq" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -485,29 +392,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "displaydoc" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" - [[package]] name = "equivalent" version = "1.0.2" @@ -563,12 +447,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -585,7 +463,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -594,34 +471,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" -[[package]] -name = "futures-executor" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" - -[[package]] -name = "futures-macro" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "futures-sink" version = "0.3.32" @@ -641,11 +490,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", - "futures-io", - "futures-macro", "futures-sink", "futures-task", - "memchr", "pin-project-lite", "slab", ] @@ -673,18 +519,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", -] - [[package]] name = "getrandom" version = "0.4.2" @@ -692,13 +526,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", - "js-sys", "libc", - "r-efi 6.0.0", - "rand_core 0.10.1", + "r-efi", "wasip2", "wasip3", - "wasm-bindgen", ] [[package]] @@ -816,7 +647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4aba8078b9198d4ee315f08a44c9206614bfbc8fa6af39c2084965c13e4920" dependencies = [ "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -837,22 +668,6 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "tokio", - "tokio-rustls", - "tower-service", ] [[package]] @@ -861,21 +676,13 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", "bytes", - "futures-channel", - "futures-util", "http", "http-body", "hyper", - "ipnet", - "libc", - "percent-encoding", "pin-project-lite", - "socket2", "tokio", "tower-service", - "tracing", ] [[package]] @@ -902,115 +709,12 @@ dependencies = [ "cc", ] -[[package]] -name = "icu_collections" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" -dependencies = [ - "displaydoc", - "potential_utf", - "utf8_iter", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" - -[[package]] -name = "icu_properties" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" - -[[package]] -name = "icu_provider" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - [[package]] name = "indexmap" version = "2.14.0" @@ -1043,92 +747,18 @@ dependencies = [ "libc", ] -[[package]] -name = "ipnet" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" - [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "jni" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" -dependencies = [ - "cfg-if", - "combine", - "jni-macros", - "jni-sys", - "log", - "simd_cesu8", - "thiserror", - "walkdir", - "windows-link", -] - -[[package]] -name = "jni-macros" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" -dependencies = [ - "proc-macro2", - "quote", - "rustc_version", - "simd_cesu8", - "syn 2.0.117", -] - -[[package]] -name = "jni-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" -dependencies = [ - "jni-sys-macros", -] - -[[package]] -name = "jni-sys-macros" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" -dependencies = [ - "quote", - "syn 2.0.117", -] - -[[package]] -name = "jobserver" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" -dependencies = [ - "getrandom 0.4.2", - "libc", -] - [[package]] name = "js-sys" version = "0.3.98" @@ -1185,12 +815,6 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "litemap" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" - [[package]] name = "lock_api" version = "0.4.14" @@ -1206,12 +830,6 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "matchers" version = "0.2.0" @@ -1317,88 +935,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "opentelemetry" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" -dependencies = [ - "futures-core", - "futures-sink", - "js-sys", - "pin-project-lite", - "thiserror", - "tracing", -] - -[[package]] -name = "opentelemetry-http" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" -dependencies = [ - "async-trait", - "bytes", - "http", - "opentelemetry", - "reqwest", -] - -[[package]] -name = "opentelemetry-otlp" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" -dependencies = [ - "http", - "opentelemetry", - "opentelemetry-http", - "opentelemetry-proto", - "opentelemetry_sdk", - "prost", - "reqwest", - "thiserror", -] - -[[package]] -name = "opentelemetry-proto" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" -dependencies = [ - "opentelemetry", - "opentelemetry_sdk", - "prost", -] - -[[package]] -name = "opentelemetry-semantic-conventions" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c913ac17a6c451661ee255f4625d143e51647ae78ebd969b75e41c4442f4fe47" - -[[package]] -name = "opentelemetry_sdk" -version = "0.32.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b59f80e1ac4d5ff7a2db8fb6c80badb7f0f3f858211fba08dd9aaec750894f9" -dependencies = [ - "futures-channel", - "futures-executor", - "futures-util", - "opentelemetry", - "percent-encoding", - "portable-atomic", - "rand 0.9.5", - "thiserror", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -1447,36 +983,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "pkg-config" -version = "0.3.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" - -[[package]] -name = "portable-atomic" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" - -[[package]] -name = "potential_utf" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" -dependencies = [ - "zerovec", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "prettyplease" version = "0.2.37" @@ -1484,7 +990,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn", ] [[package]] @@ -1496,86 +1002,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "quinn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" -dependencies = [ - "aws-lc-rs", - "bytes", - "getrandom 0.4.2", - "lru-slab", - "rand 0.10.2", - "rand_pcg", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - [[package]] name = "quote" version = "1.0.45" @@ -1585,73 +1011,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" -dependencies = [ - "rand_chacha", - "rand_core 0.9.5", -] - -[[package]] -name = "rand" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" -dependencies = [ - "chacha20", - "getrandom 0.4.2", - "rand_core 0.10.1", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.5", -] - -[[package]] -name = "rand_core" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_core" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" - -[[package]] -name = "rand_pcg" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" -dependencies = [ - "rand_core 0.10.1", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -1690,57 +1055,6 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" -[[package]] -name = "reqwest" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "rustls-platform-verifier", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rmp" version = "0.8.15" @@ -1760,21 +1074,6 @@ dependencies = [ "serde", ] -[[package]] -name = "rustc-hash" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "1.1.4" @@ -1788,81 +1087,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "rustls" -version = "0.23.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138" -dependencies = [ - "aws-lc-rs", - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pki-types" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-platform-verifier" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" -dependencies = [ - "core-foundation", - "core-foundation-sys", - "jni", - "log", - "once_cell", - "rustls", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki", - "security-framework", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.60.2", -] - -[[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" - -[[package]] -name = "rustls-webpki" -version = "0.103.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.22" @@ -1884,44 +1108,12 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "schannel" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "security-framework" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.28" @@ -1955,7 +1147,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -2043,22 +1235,6 @@ dependencies = [ "libc", ] -[[package]] -name = "simd_cesu8" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" -dependencies = [ - "rustc_version", - "simdutf8", -] - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - [[package]] name = "slab" version = "0.4.12" @@ -2090,12 +1266,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "stable_deref_trait" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" - [[package]] name = "strsim" version = "0.11.1" @@ -2119,36 +1289,11 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] [[package]] name = "tempfile" @@ -2180,7 +1325,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -2192,31 +1337,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "tinystr" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" version = "1.52.3" @@ -2242,17 +1362,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", + "syn", ] [[package]] @@ -2292,15 +1402,12 @@ checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ "bitflags", "bytes", - "futures-util", "http", "http-body", "pin-project-lite", - "tower", "tower-layer", "tower-service", "tracing", - "url", ] [[package]] @@ -2335,7 +1442,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -2377,12 +1484,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - [[package]] name = "typenum" version = "1.20.0" @@ -2407,36 +1508,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "unty" version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" -[[package]] -name = "url" -version = "2.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - [[package]] name = "utf8parse" version = "0.2.2" @@ -2471,15 +1548,6 @@ dependencies = [ "winapi-util", ] -[[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.11.1+wasi-snapshot-preview1" @@ -2517,16 +1585,6 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "wasm-bindgen-macro" version = "0.2.121" @@ -2546,7 +1604,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn", "wasm-bindgen-shared", ] @@ -2593,35 +1651,6 @@ dependencies = [ "semver", ] -[[package]] -name = "web-sys" -version = "0.3.98" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "winapi-util" version = "0.1.11" @@ -2652,7 +1681,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -2663,7 +1692,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn", ] [[package]] @@ -2690,22 +1719,13 @@ dependencies = [ "windows-link", ] -[[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.6", -] - [[package]] name = "windows-sys" version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.5", + "windows-targets", ] [[package]] @@ -2717,22 +1737,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - [[package]] name = "windows-targets" version = "0.53.5" @@ -2740,106 +1744,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - [[package]] name = "windows_aarch64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - [[package]] name = "windows_aarch64_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - [[package]] name = "windows_i686_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - [[package]] name = "windows_i686_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - [[package]] name = "windows_i686_msvc" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - [[package]] name = "windows_x86_64_gnu" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - [[package]] name = "windows_x86_64_gnullvm" version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "windows_x86_64_msvc" version = "0.53.1" @@ -2882,7 +1838,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.117", + "syn", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -2898,7 +1854,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", + "syn", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -2940,115 +1896,6 @@ dependencies = [ "wasmparser", ] -[[package]] -name = "writeable" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" - -[[package]] -name = "yoke" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "zerofrom" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" - -[[package]] -name = "zerotrie" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "zmij" version = "1.0.21" diff --git a/Cargo.toml b/Cargo.toml index 077aa42..b98363a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "anwesen" description = "Read-only HTTP daemon over a markdown vault, querying YAML frontmatter." -version = "0.4.0" +version = "0.1.0" edition = "2024" rust-version = "1.95" license = "BSD-3-Clause" @@ -17,17 +17,8 @@ axum = "0.8" blake3 = "1" chrono = { version = "0.4", default-features = false, features = ["std", "serde", "clock"] } clap = { version = "4", features = ["derive", "env"] } -http-body = "1" hydra = "0.1" notify = "8" -opentelemetry = "0.32" -# `reqwest-rustls` is required alongside `reqwest-blocking-client`: the -# default otlp features wire reqwest with no TLS backend at all, so HTTPS to -# the collector would fail. rustls (aws-lc-rs + OS trust store) keeps the -# release binary free of a system OpenSSL dependency. -opentelemetry-otlp = { version = "0.32", default-features = false, features = ["trace", "metrics", "http-proto", "reqwest-blocking-client", "reqwest-rustls"] } -opentelemetry-semantic-conventions = "0.32" -opentelemetry_sdk = { version = "0.32", features = ["metrics", "trace"] } regex = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/README.md b/README.md index f51daa3..33cac92 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Anwesen answers three kinds of question over HTTP: The frontmatter index is built once at startup and kept current by watching the vault directory. The index lives in memory; a restart rebuilds it, and there is nothing on disk to corrupt or migrate. -The same query-and-merge engine also runs offline, with no server. `anwesen merge` walks a directory, evaluates a query, and writes the merged markdown to stdout; `anwesen query` writes the same JSON document `GET /query` returns (see [Local generation](#local-generation)). +The same query-and-merge engine also runs offline, with no server: `anwesen merge` walks a directory, evaluates a query, and writes the merged markdown to stdout (see [Local generation](#local-generation)). ## Quick start @@ -52,86 +52,29 @@ Build one file out of many notes, without starting the daemon: anwesen merge --vault /path/to/vault --query 'tags=adr&__anw-order=title' > ADRs.md ``` -Ask which notes match, and what their frontmatter holds, without starting the daemon: - -``` -anwesen query --vault /path/to/vault --query 'tags=adr' | jq -r '.results[].path' -``` - ## CLI ``` anwesen serve --vault [--bind ] [--log-level ] - [--otlp-slow-request-ms ] anwesen doctor --vault anwesen merge --vault --query -anwesen query --vault --query anwesen version ``` -| Flag | Env var | Default | Meaning | -| --------------------------- | ------------------------------ | ---------------------- | ----------------------------------------------------------------------------- | -| `--vault ` | `ANWESEN_VAULT` | _required_ | Path to the vault root. | -| `--bind ` | `ANWESEN_BIND` | `127.0.0.1:8080` | Listen address for `serve`. | -| `--log-level ` | `ANWESEN_LOG_LEVEL` | `info` | `error`, `warn`, `info`, `debug`, or `trace`. | -| `--query ` | `ANWESEN_QUERY` | empty (match all) | A `/query` query string: frontmatter predicates plus `__anw-` controls. `merge` and `query` only. | -| `--otlp-slow-request-ms` | `ANWESEN_OTLP_SLOW_REQUEST_MS` | `500` | Requests at or over this duration, or answering 5xx, also export a span. | +| Flag | Env var | Default | Meaning | +| ------------------------ | ------------------- | ---------------------- | ----------------------------------------------------------------------- | +| `--vault ` | `ANWESEN_VAULT` | _required_ | Path to the vault root. | +| `--bind ` | `ANWESEN_BIND` | `127.0.0.1:8080` | Listen address for `serve`. | +| `--log-level ` | `ANWESEN_LOG_LEVEL` | `info` | `error`, `warn`, `info`, `debug`, or `trace`. | +| `--query ` | -- | _required for `merge`_ | A `/query` query string: frontmatter predicates plus `__anw-` controls. | -Every flag has a matching `ANWESEN_` environment variable. CLI flags win -over env vars. - -`--bind` and `--otlp-slow-request-ms` apply to `serve` only. Where telemetry is -exported is configured entirely through the standard `OTEL_` variables below. +Every flag has a matching `ANWESEN_` environment variable; CLI flags win over env vars. - **`serve`** -- run the daemon: walk the vault, build the index, watch for changes, serve the API. - **`doctor`** -- walk the vault once and report what would stop clean ingestion: unreadable files, unparseable YAML, path collisions on the HTTP surface, and frontmatter type drift (the same key carrying incompatible types across notes). Read-only; non-zero exit if any issue is found. - **`merge`** -- one-shot local generation: walk the vault, evaluate `--query`, and write the merged markdown document to stdout. No server, no HTTP. See [Local generation](#local-generation). -- **`query`** -- the same one-shot walk, writing the JSON document `GET /query` returns: which notes match, and what their frontmatter, `last_modified`, `etag` and `size` hold. No server, no HTTP. See [Local generation](#local-generation). - **`version`** -- print version and exit. -## Telemetry - -anwesen exports OTLP metrics for every request, and a span for requests at or -over `--otlp-slow-request-ms` or answering a 5xx. Export is configured through -the standard OpenTelemetry environment variables, which the SDK reads directly: - -| Variable | Meaning | -| -------------------------------------- | ---------------------------------------------------------------- | -| `OTEL_EXPORTER_OTLP_ENDPOINT` | Base URL. The SDK appends `/v1/metrics` and `/v1/traces`. | -| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | Full metrics URL, used as given. Overrides the base for metrics. | -| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Full traces URL, used as given. Overrides the base for traces. | -| `OTEL_EXPORTER_OTLP_HEADERS` | Export headers, `key=value` comma-separated. | -| `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/protobuf`, the default and the only value this build speaks. | -| `OTEL_SERVICE_NAME`, `OTEL_RESOURCE_ATTRIBUTES` | Override the `anwesen` service identity. | - -The per-signal `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL` and -`OTEL_EXPORTER_OTLP_TRACES_PROTOCOL` are read the same way. - -With none of the three endpoint variables set, telemetry is off: no exporter is -built and the request middleware is not installed. - -Two settings fail at startup rather than export nowhere in silence: - -- A query or a fragment on `OTEL_EXPORTER_OTLP_ENDPOINT`. The base URL must be - a base URL; the SDK appends the signal path after whatever it is given. -- A protocol other than `http/protobuf`. The binary ships the OTLP/HTTP - transport alone, so `grpc` would keep exporting over HTTP with nothing in the - log. Point the endpoint at the collector's HTTP port, not its gRPC one. - -uptrace: - -``` -OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev -OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=https://TOKEN@api.uptrace.dev?grpc=4317 -``` - -Paste the DSN from Project Settings into the header verbatim, tail and all -- -it is a credential there, not an address. The endpoint is the host alone. - -Removed in 0.3.0: `--uptrace-dsn`, `--otlp-endpoint`, `--otlp-header` and their -`ANWESEN_` variables. Passing any of them fails at startup with the `OTEL_` -replacement to use. - ## HTTP API All endpoints are `GET` and return JSON unless noted. @@ -181,7 +124,7 @@ ISO-8601 dates and RFC 3339 datetimes are coerced to typed dates at read time, s | `__anw-order=[:asc\|:desc]` | path order | Order fragments (merge mode only). | | `__anw-kind=` | off | Refuse a mixed merge unless every matched note shares one value for the key (merge mode only). | -By default `/query` returns metadata only; fetch bodies with `/notes/`. The same JSON document is available offline, without the daemon, via `anwesen query` (see [Local generation](#local-generation)). +By default `/query` returns metadata only; fetch bodies with `/notes/`. #### Markdown-merge mode @@ -209,11 +152,7 @@ Returns vault path, note count, last index/event timestamps, watcher state, an i ## Local generation -Two subcommands answer a query on the command line, with no server and no HTTP round-trip: `merge` writes the merged markdown document, `query` writes the JSON projection. Both take the same `--vault` and `--query` flags, both walk the vault once, and both run the engine the endpoint runs -- so the output matches what the daemon would have returned for the same vault and query. - -### `merge` - -`anwesen merge` walks the vault, evaluates the query, and writes the merged document to stdout: +`anwesen merge` produces the markdown-merge document on the command line, with no server and no HTTP round-trip. It walks the vault, evaluates the query, and writes the merged document to stdout: ``` anwesen merge --vault /path/to/vault --query 'tags=adr&__anw-order=title&__anw-kind=kind' @@ -223,24 +162,6 @@ The `--query` string is the exact `/query` grammar: frontmatter predicates plus This is the materialization path: build a `CLAUDE.md`, a skill bundle, or any single file assembled from many notes, driven from a script or a one-off shell. -### `query` - -`anwesen query` answers the other half: which notes match, and what their frontmatter holds. It writes the same JSON document `GET /query` returns -- `results`, `total`, `truncated`, with `path`, `frontmatter`, `last_modified`, `etag` and `size` per row -- on one line, ready for `jq`: - -``` -anwesen query --vault /path/to/vault --query 'kind=PDR&__anw-limit=1' -``` - -```json -{"results":[{"path":"Projects/PDR-001-intro.md","frontmatter":{"kind":"PDR","num":1,"title":"PDR-001 Intro"},"last_modified":"2026-05-14T17:05:08Z","etag":"\"f657eab5...\"","size":57}],"total":2,"truncated":true} -``` - -`total` counts the full match set; `truncated` says the cap cut it. - -Bodies are elided here as they are on the endpoint; `merge` is the way to get them offline. `__anw-order` and `__anw-kind` are merge-mode controls and do not affect this output. A malformed query or an unreadable vault exits non-zero with the reason on stderr; an empty match set is an empty `results` list and exit `0`. - -A script can therefore move between the daemon and the CLI without a second parser: same shape, same field names, same timestamp dialect. - ## Design notes - **In place, read-only.** Anwesen reads the same directory Obsidian writes to and never writes back. The vault stays editable in Obsidian with no coordination, and there is no write API by design. diff --git a/src/app.rs b/src/app.rs index cc4bcf6..5677d57 100644 --- a/src/app.rs +++ b/src/app.rs @@ -40,7 +40,6 @@ use tokio::task::JoinHandle; use crate::health::HealthState; use crate::http::{self as http_layer, HttpState}; use crate::store::NoteStore; -use crate::telemetry::Telemetry; use crate::vault::{self, Note}; use crate::watcher::run_debouncer; @@ -118,28 +117,17 @@ pub struct Anwesen { pub store: Arc, /// Shared mutable health surface consumed by `/health` ([ANW-8]). pub health: Arc, - /// Request-level telemetry handle ([ANW-37]). `None` disables export and - /// the request middleware entirely. - pub telemetry: Option>, - /// Set once the supervisor tree is up. Hydra's `Application::run` logs a - /// start failure and returns normally, so `serve` cannot tell a clean - /// shutdown from a tree that never came up. `main` reads this after `run` - /// and exits nonzero when it is still false, which is what lets systemd - /// retry ([ANW-45](https://crvrs.youtrack.cloud/issue/ANW-45)). - pub started: Arc, } impl Anwesen { #[must_use] - pub fn new(vault: PathBuf, bind: SocketAddr, telemetry: Option>) -> Self { + pub fn new(vault: PathBuf, bind: SocketAddr) -> Self { Self { vault, bind, counters: RestartCounters::new(), store: NoteStore::new(), health: HealthState::new(), - telemetry, - started: Arc::new(AtomicBool::new(false)), } } } @@ -189,17 +177,14 @@ impl Application for Anwesen { store: self.store.clone(), health: self.health.clone(), vault: self.vault.clone(), - telemetry: self.telemetry.clone(), } .child_spec(), ]; - let pid = Supervisor::with_children(children) + Supervisor::with_children(children) .strategy(SupervisionStrategy::OneForOne) .start_link(SupervisorOptions::new().name("anwesen_root")) - .await?; - self.started.store(true, Ordering::Release); - Ok(pid) + .await } } @@ -451,14 +436,6 @@ pub enum IndexWriterMessage { pub struct IndexBatch { pub upserts: Vec, pub deletes: Vec, - /// Directories whose indexed notes all drop before the upserts land. A - /// removed or renamed directory produces no per-file event, so the - /// prefix is the only handle on those notes. A directory that was - /// walked is listed here too: the index under that prefix has to match - /// the walk, not keep what an earlier directory of the same name left - /// behind [ANW-36]. - #[serde(default)] - pub delete_prefixes: Vec, } #[derive(Clone)] @@ -515,15 +492,8 @@ impl GenServer for IndexWriterState { } IndexWriterMessage::Batch(batch) => { let (u, d) = (batch.upserts.len(), batch.deletes.len()); - let dropped = - self.store - .apply_batch(batch.upserts, &batch.deletes, &batch.delete_prefixes); - tracing::info!( - upserts = u, - deletes = d, - dropped, - "index_writer: batch applied" - ); + self.store.apply_batch(batch.upserts, &batch.deletes); + tracing::info!(upserts = u, deletes = d, "index_writer: batch applied"); } IndexWriterMessage::Upsert(note) => { let path = note.path.clone(); @@ -565,7 +535,6 @@ pub struct HttpServer { store: Arc, health: Arc, vault: PathBuf, - telemetry: Option>, } impl HttpServer { @@ -575,14 +544,12 @@ impl HttpServer { let store = self.store.clone(); let health = self.health.clone(); let vault = self.vault.clone(); - let telemetry = self.telemetry.clone(); ChildSpec::new(HTTP_SERVER_NAME).start(move || { let bind = bind; let counters = counters.clone(); let store = store.clone(); let health = health.clone(); let vault = vault.clone(); - let telemetry = telemetry.clone(); async move { // Bind eagerly so the supervisor sees `bind: : ...` // as the start error rather than a successful spawn that @@ -591,15 +558,12 @@ impl HttpServer { .await .map_err(|e| ExitReason::from(format!("http_server: bind {bind}: {e}")))?; let restart = counters.http_server.record_init(); - let router = http_layer::router( - HttpState { - store, - health, - restart_counters: counters, - vault, - }, - telemetry, - ); + let router = http_layer::router(HttpState { + store, + health, + restart_counters: counters, + vault, + }); let pid = Process::spawn_link(async move { Process::set_flags(ProcessFlags::TRAP_EXIT); tracing::info!(restart, bind = %bind, "http_server: init"); diff --git a/src/cli.rs b/src/cli.rs index 32bbced..c3b1f21 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -4,27 +4,14 @@ //! //! ```text //! anwesen serve --vault [--bind ] [--log-level ] -//! [--otlp-slow-request-ms ] //! anwesen doctor --vault [--log-level ] //! anwesen merge --vault [--query ] [--log-level ] -//! anwesen query --vault [--query ] [--log-level ] //! anwesen version //! ``` //! -//! `merge` and `query` differ only in what they write -- the merged markdown -//! document or the `/query` JSON projection ([ANW-43]) -- so they share one -//! [`VaultQueryArgs`] flag set and cannot drift. -//! -//! `--bind` and `--otlp-slow-request-ms` are `serve`-only ([ANW-37]); -//! `doctor` and `merge` do not bind a port; `version` takes no flags. Each -//! flag has a matching `ANWESEN_` environment variable and CLI wins -//! over env per the manual. -//! -//! Telemetry export is configured through the standard `OTEL_EXPORTER_OTLP_*` -//! environment variables ([ANW-42](https://crvrs.youtrack.cloud/issue/ANW-42)). -//! With none of them set, telemetry is off and the server behaves as it did -//! before telemetry existed. The removed flags below are still parsed so an -//! upgrade fails loudly instead of dropping export config in silence. +//! `--bind` is `serve`-only; `doctor` and `merge` do not bind a port; +//! `version` takes no flags. Each flag has a matching `ANWESEN_` +//! environment variable and CLI wins over env per the manual. use std::net::SocketAddr; use std::path::PathBuf; @@ -46,11 +33,7 @@ pub enum Command { Doctor(DoctorArgs), /// Walk the vault once, evaluate the query, and write the merged markdown /// document to stdout. One-shot; no server. Read-only. - Merge(VaultQueryArgs), - /// Walk the vault once, evaluate the query, and write the same JSON - /// document `GET /query` returns to stdout. One-shot; no server. - /// Read-only. - Query(VaultQueryArgs), + Merge(MergeArgs), /// Print the version and exit. Version, } @@ -68,31 +51,6 @@ pub struct ServeArgs { /// Log verbosity. #[arg(long, env = "ANWESEN_LOG_LEVEL", default_value = "info")] pub log_level: LogLevel, - - /// Removed (ANW-42): use `OTEL_EXPORTER_OTLP_ENDPOINT` plus - /// `OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=`. Still accepted so - /// startup fails with that message rather than exporting nowhere. - #[arg(long, env = "ANWESEN_UPTRACE_DSN", hide = true)] - pub uptrace_dsn: Option, - - /// Removed (ANW-42): use `OTEL_EXPORTER_OTLP_ENDPOINT`. - #[arg(long, env = "ANWESEN_OTLP_ENDPOINT", hide = true)] - pub otlp_endpoint: Option, - - /// Removed (ANW-42): use `OTEL_EXPORTER_OTLP_HEADERS`. - #[arg( - long = "otlp-header", - env = "ANWESEN_OTLP_HEADERS", - value_delimiter = ',', - hide = true - )] - pub otlp_headers: Vec, - - /// Requests at or over this duration in milliseconds, or answering a - /// 5xx, are additionally recorded as OTLP server spans; every other - /// request stays metrics-only. - #[arg(long, env = "ANWESEN_OTLP_SLOW_REQUEST_MS", default_value = "500")] - pub otlp_slow_request_ms: u64, } #[derive(Debug, clap::Args)] @@ -106,9 +64,8 @@ pub struct DoctorArgs { pub log_level: LogLevel, } -/// Flags shared by the two one-shot subcommands, `merge` and `query`. #[derive(Debug, clap::Args)] -pub struct VaultQueryArgs { +pub struct MergeArgs { /// Path to the vault root. #[arg(long, env = "ANWESEN_VAULT")] pub vault: PathBuf, @@ -116,12 +73,12 @@ pub struct VaultQueryArgs { /// Query in the `/query` query-string grammar, for example /// `tags=anwesen&__anw-kind=skill&__anw-order=order`. The `__anw-kind` /// homogeneity guard and `__anw-order` fragment ordering ride inside this - /// string -- there are no separate flags. `__anw-kind` and `__anw-order` - /// apply to `merge` only. Empty matches every note under the vault root. + /// string -- there are no separate flags. Empty merges every note under + /// the vault root. #[arg(long, env = "ANWESEN_QUERY", default_value = "")] pub query: String, - /// Log verbosity. Logs go to stderr; the document goes to stdout. + /// Log verbosity. Logs go to stderr; the merged document goes to stdout. #[arg(long, env = "ANWESEN_LOG_LEVEL", default_value = "info")] pub log_level: LogLevel, } @@ -183,34 +140,6 @@ mod tests { } } - /// The removed telemetry flags still parse, hidden from `--help`. Clap - /// rejecting them as unknown would say nothing about the `OTEL_` - /// replacement; the migration error in `telemetry::TelemetryConfig` - /// needs the values to reach it (ANW-42). - #[test] - fn serve_still_parses_the_removed_telemetry_flags() { - let cli = parse(&[ - "serve", - "--vault", - "/tmp/v", - "--uptrace-dsn", - "https://tok@api.uptrace.dev", - "--otlp-endpoint", - "https://collector.example.com", - "--otlp-header", - "authorization=Bearer xyz", - ]) - .expect("parse"); - match cli.command { - Command::Serve(a) => { - assert!(a.uptrace_dsn.is_some()); - assert!(a.otlp_endpoint.is_some()); - assert_eq!(a.otlp_headers, vec!["authorization=Bearer xyz".to_string()]); - } - _ => panic!("expected serve"), - } - } - #[test] fn serve_rejects_malformed_bind_at_parse_time() { let err = parse(&["serve", "--vault", "/tmp/v", "--bind", "not-an-addr"]).unwrap_err(); @@ -281,47 +210,6 @@ mod tests { assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument); } - #[test] - fn query_takes_the_same_flags_as_merge() { - let cli = parse(&[ - "query", - "--vault", - "/tmp/v", - "--query", - "tags=anwesen&__anw-limit=5", - "--log-level", - "warn", - ]) - .expect("parse"); - match cli.command { - Command::Query(a) => { - assert_eq!(a.vault, PathBuf::from("/tmp/v")); - assert_eq!(a.query, "tags=anwesen&__anw-limit=5"); - assert!(matches!(a.log_level, LogLevel::Warn)); - } - _ => panic!("expected query"), - } - } - - #[test] - fn query_requires_vault_and_defaults_the_query() { - assert!(parse(&["query"]).is_err()); - match parse(&["query", "--vault", "/tmp/v"]) - .expect("parse") - .command - { - Command::Query(a) => assert_eq!(a.query, ""), - _ => panic!("expected query"), - } - } - - #[test] - fn query_rejects_bind() { - // --bind is serve-only; query does not listen. - let err = parse(&["query", "--vault", "/tmp/v", "--bind", "0.0.0.0:9000"]).unwrap_err(); - assert_eq!(err.kind(), clap::error::ErrorKind::UnknownArgument); - } - #[test] fn version_takes_no_flags() { assert!(matches!( diff --git a/src/doctor.rs b/src/doctor.rs index f53f09f..58f3e8d 100644 --- a/src/doctor.rs +++ b/src/doctor.rs @@ -46,7 +46,7 @@ pub struct DriftShape { /// `"bool"`, `"number"`, `"string"`, `"date"`, `"list"`, `"mapping"`. pub shape: &'static str, pub count: usize, - /// Up to `DRIFT_SAMPLES_PER_SHAPE` vault-relative paths exhibiting + /// Up to [`DRIFT_SAMPLES_PER_SHAPE`] vault-relative paths exhibiting /// this shape, in the order they were scanned. pub samples: Vec, } diff --git a/src/http.rs b/src/http.rs index 1d847a9..9296811 100644 --- a/src/http.rs +++ b/src/http.rs @@ -12,18 +12,16 @@ //! `/health` ([ANW-8]) onto the same [`Router`]. use std::sync::Arc; -use std::time::{Instant, SystemTime}; use axum::Router; use axum::body::Body; use axum::extract::{OriginalUri, Path as AxumPath, Request, State}; -use axum::http::header::{ACCEPT, CONTENT_LENGTH, CONTENT_TYPE, ETAG, IF_NONE_MATCH}; +use axum::http::header::{ACCEPT, CONTENT_TYPE, ETAG, IF_NONE_MATCH}; use axum::http::{HeaderMap, HeaderValue, StatusCode}; -use axum::middleware::{Next, from_fn, from_fn_with_state}; +use axum::middleware::{Next, from_fn}; use axum::response::{IntoResponse, Response}; use axum::routing::get; -use chrono::{DateTime, Utc}; -use http_body::Body as _; +use chrono::{DateTime, SecondsFormat, Utc}; use hydra::Process; use serde::Serialize; use std::collections::BTreeMap; @@ -32,11 +30,16 @@ use std::path::PathBuf; use crate::app::RestartCounters; use crate::health::HealthState; -use crate::query::rfc3339_z; use crate::store::NoteStore; -use crate::telemetry::{self, Telemetry, TraceHeaders}; use crate::vault::{Note, frontmatter_to_json}; +/// Canonical RFC 3339 form with a `Z` suffix -- the shape the User Manual +/// example uses for `last_modified`. Centralized here so every HTTP +/// `last_modified` field stays in the same dialect. +fn rfc3339_z(dt: DateTime) -> String { + dt.to_rfc3339_opts(SecondsFormat::Secs, true) +} + /// Shared state injected into every handler. #[derive(Clone)] pub struct HttpState { @@ -46,72 +49,18 @@ pub struct HttpState { pub vault: PathBuf, } -pub fn router(state: HttpState, telemetry: Option>) -> Router { +pub fn router(state: HttpState) -> Router { // `/notes/{*path}` is greedy and includes any trailing slash; one // handler dispatches read-one vs folder-listing on that suffix. The // root listing (`/notes/`) needs its own route since the wildcard // requires at least one character. - let router = Router::new() + Router::new() .route("/notes/", get(list_root_folder)) .route("/notes/{*path}", get(get_notes)) .route("/query", get(get_query)) .route("/health", get(get_health)) - .layer(from_fn(process_wrap)); - // Telemetry is the outermost layer so it observes the final response, - // including the `500` that `process_wrap` synthesizes on a handler - // panic. Installed only when export is configured; a config-less server - // never runs this layer and is byte-for-byte as before ([ANW-37]). - let router = match telemetry { - Some(tel) => router.layer(from_fn_with_state(tel, telemetry_wrap)), - None => router, - }; - router.with_state(state) -} - -/// Outermost middleware: time the request, classify its route, and hand the -/// completed observation to [`Telemetry`]. Trace-context headers are captured -/// up front (the handler consumes the request); the parent context is only -/// extracted later if the request turns out slow enough to span. -async fn telemetry_wrap( - State(tel): State>, - request: Request, - next: Next, -) -> Response { - let start_instant = Instant::now(); - let start_wall = SystemTime::now(); - let route = telemetry::classify_route(request.uri().path()); - let method = request.method().clone(); - let if_none_match_present = request.headers().contains_key(IF_NONE_MATCH); - let trace = TraceHeaders::from_headers(request.headers()); - - let response = next.run(request).await; - - let status = response.status().as_u16(); - // In-memory handler bodies carry an exact size hint; fall back to a - // Content-Length header, then to 0, so a streaming body never panics. - let body_bytes = response - .body() - .size_hint() - .exact() - .or_else(|| content_length(response.headers())) - .unwrap_or(0); - let duration = start_instant.elapsed(); - - tel.finish( - route, - method.as_str(), - status, - if_none_match_present, - body_bytes, - duration, - start_wall, - &trace, - ); - response -} - -fn content_length(headers: &HeaderMap) -> Option { - headers.get(CONTENT_LENGTH)?.to_str().ok()?.parse().ok() + .layer(from_fn(process_wrap)) + .with_state(state) } /// Per [ANW-25](https://crvrs.youtrack.cloud/issue/ANW-25): run each request @@ -511,15 +460,12 @@ mod tests { fn router_with(notes: Vec) -> (Router, Arc) { let store = NoteStore::new(); store.replace(notes); - let r = router( - HttpState { - store: store.clone(), - health: crate::health::HealthState::new(), - restart_counters: crate::app::RestartCounters::new(), - vault: PathBuf::from("/test/vault"), - }, - None, - ); + let r = router(HttpState { + store: store.clone(), + health: crate::health::HealthState::new(), + restart_counters: crate::app::RestartCounters::new(), + vault: PathBuf::from("/test/vault"), + }); (r, store) } @@ -811,51 +757,4 @@ mod tests { assert!(resolve_path("").is_err()); assert!(resolve_path("a/%ZZ.md").is_err()); } - - /// With telemetry installed, a normal request is answered byte-for-byte - /// as without it. The test process sets no `OTEL_EXPORTER_OTLP_*` - /// variables, so the exporter aims at the SDK default and fails in the - /// background without ever touching the response path. - #[tokio::test] - async fn telemetry_layer_does_not_alter_responses() { - use crate::telemetry::{self, OtelEnv, RawTelemetryArgs, TelemetryConfig}; - - let cfg = TelemetryConfig::resolve( - &RawTelemetryArgs { - slow_request_ms: 500, - ..Default::default() - }, - OtelEnv { - endpoint: Some("http://127.0.0.1:9".into()), - ..OtelEnv::default() - }, - ) - .unwrap() - .expect("telemetry on"); - let tel = Arc::new(telemetry::init(cfg).expect("telemetry init")); - - let n = note("a.md", "body"); - let expected_etag = n.etag.clone(); - let store = NoteStore::new(); - store.replace(vec![n]); - let r = router( - HttpState { - store, - health: crate::health::HealthState::new(), - restart_counters: crate::app::RestartCounters::new(), - vault: PathBuf::from("/test/vault"), - }, - Some(tel.clone()), - ); - let req = Request::get("/notes/a.md").body(Body::empty()).unwrap(); - let resp = send(r, req).await; - assert_eq!(resp.status(), StatusCode::OK); - assert_eq!(resp.headers().get(ETAG).unwrap(), expected_etag.as_str()); - let bytes = to_bytes(resp.into_body(), 64 * 1024).await.unwrap(); - let v: serde_json::Value = serde_json::from_slice(&bytes).unwrap(); - assert_eq!(v["path"], "a.md"); - assert_eq!(v["body"], "body"); - - tel.shutdown(); - } } diff --git a/src/lib.rs b/src/lib.rs index 818b23e..0111390 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,9 +10,8 @@ pub mod app; pub mod doctor; pub mod health; pub mod http; -pub mod oneshot; +pub mod merge; pub mod query; pub mod store; -pub mod telemetry; pub mod vault; pub mod watcher; diff --git a/src/main.rs b/src/main.rs index 05027d9..f265ced 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,17 +1,13 @@ //! Anwesen: read-only HTTP daemon over a markdown vault. //! -//! This module wires the CLI to the `serve`, `doctor`, `merge`, `query`, and +//! This module wires the CLI to the `serve`, `doctor`, `merge`, and //! `version` subcommands. mod cli; -use std::sync::Arc; -use std::sync::atomic::Ordering; - use anwesen::app::Anwesen; use anwesen::doctor; -use anwesen::oneshot; -use anwesen::telemetry::{self, OtelEnv, RawTelemetryArgs, TelemetryConfig}; +use anwesen::merge; use anyhow::Result; use clap::Parser; use hydra::Application; @@ -19,50 +15,21 @@ use hydra::Application; use crate::cli::{Cli, Command}; // Result is retained at the binary boundary per [[ADR-001 Language and -// Foundation Libraries]] (anyhow at main); telemetry config resolution and -// exporter setup surface startup errors through it. +// Foundation Libraries]] (anyhow at main); current stubs do not yet +// surface errors. +#[allow(clippy::unnecessary_wraps)] fn main() -> Result<()> { let cli = Cli::parse(); match cli.command { Command::Serve(args) => { init_logging(args.log_level); - // Resolve telemetry config before the supervisor starts; no - // OTEL_EXPORTER_OTLP_* endpoint leaves it `None` (export off, - // no middleware). A removed flag is a startup error (ANW-42). - let telemetry = match TelemetryConfig::resolve( - &RawTelemetryArgs { - uptrace_dsn: args.uptrace_dsn, - otlp_endpoint: args.otlp_endpoint, - otlp_headers: args.otlp_headers, - slow_request_ms: args.otlp_slow_request_ms, - }, - OtelEnv::from_env(), - )? { - Some(cfg) => Some(Arc::new(telemetry::init(cfg)?)), - None => None, - }; tracing::info!( vault = %args.vault.display(), bind = %args.bind, - telemetry = telemetry.is_some(), "anwesen serve: starting supervisor tree" ); - let app = Anwesen::new(args.vault, args.bind, telemetry.clone()); - let started = app.started.clone(); // Blocks until the supervisor exits (SIGTERM / SIGINT / crash). - app.run(); - // Flush and shut down exporters after the server loop returns. - if let Some(telemetry) = telemetry { - telemetry.shutdown(); - } - // `run` returns normally whether the tree came up or never - // started, so a failed start would otherwise look like a clean - // exit and systemd's `Restart=on-failure` would not retry - // (ANW-45). Exit nonzero when the tree never came up. - if !started.load(Ordering::Acquire) { - tracing::error!("anwesen serve: supervisor tree failed to start"); - std::process::exit(1); - } + Anwesen::new(args.vault, args.bind).run(); } Command::Doctor(args) => { init_logging(args.log_level); @@ -74,26 +41,13 @@ fn main() -> Result<()> { } Command::Merge(args) => { init_logging(args.log_level); - match oneshot::merge(&args.vault, &args.query) { + match merge::run(&args.vault, &args.query) { // `print!`, not `println!`: the merged document is byte-stable // and byte-identical to the HTTP merge body, which carries no // trailing newline. An empty match set prints nothing, exit 0. Ok(doc) => print!("{doc}"), Err(e) => { - eprint!("{}", e.render("merge")); - std::process::exit(1); - } - } - } - Command::Query(args) => { - init_logging(args.log_level); - match oneshot::query_json(&args.vault, &args.query) { - // `println!` here, unlike `merge`: the JSON body carries no - // trailing newline either, but stdout is one document per - // line for the shells and `jq` pipelines this exists for. - Ok(doc) => println!("{doc}"), - Err(e) => { - eprint!("{}", e.render("query")); + eprint!("{}", e.render()); std::process::exit(1); } } diff --git a/src/merge.rs b/src/merge.rs new file mode 100644 index 0000000..a9b6d2b --- /dev/null +++ b/src/merge.rs @@ -0,0 +1,205 @@ +//! One-shot local markdown-merge for the `anwesen merge` subcommand ([ANW-27]). +//! +//! Walks a vault directory once (the same [`vault::scan`] as `doctor`), +//! evaluates the `--query` string, and assembles the merged markdown document +//! with [`query::execute_merge`] -- the very engine the HTTP `/query` merge +//! mode ([ANW-26]) uses. CLI and HTTP output are therefore byte-identical for +//! the same vault and query. No HTTP, no watcher, no persistent index. + +use std::fmt::Write as _; +use std::path::Path; + +use crate::query::{self, MergeError, QueryError}; +use crate::store::NoteStore; +use crate::vault::{self, ScanIssue}; + +/// Why a one-shot merge could not produce a document. +#[derive(Debug)] +pub enum MergeCliError { + /// The `--query` string did not parse. Same grammar, same message as the + /// HTTP `/query` `400`. + Query(QueryError), + /// One or more files could not be read, or their frontmatter did not + /// parse. Same hard-failure posture as `doctor`; soft warnings (e.g. a + /// non-mapping frontmatter root) are ignored, matching what `serve` + /// ingests. + Scan(Vec), + /// The `__anw-kind` homogeneity guard rejected the matched set. The + /// `String` is the same naming message the HTTP path returns as `400`, + /// surfaced here on stderr instead. + Kind(String), +} + +impl MergeCliError { + /// Render the error for stderr. One concern per line, deterministic so the + /// stderr surface is golden-testable. + #[must_use] + pub fn render(&self) -> String { + match self { + Self::Query(e) => format!("{e}\n"), + Self::Scan(issues) => { + let mut s = String::from("merge: cannot read vault\n"); + for issue in issues { + let _ = writeln!(s, " {}: {}", issue.path.display(), issue.kind); + } + s + } + Self::Kind(msg) => msg.clone(), + } + } +} + +/// Walk `vault_root`, evaluate `raw_query`, and return the merged document. +/// +/// On success the returned `String` is byte-identical to the HTTP merge body +/// for the same vault and query. An empty match set yields an empty string. +/// +/// # Errors +/// - [`MergeCliError::Query`] when `raw_query` is malformed; +/// - [`MergeCliError::Scan`] when the directory is unreadable or any file's +/// frontmatter fails to parse; +/// - [`MergeCliError::Kind`] when the `__anw-kind` homogeneity guard fails. +pub fn run(vault_root: &Path, raw_query: &str) -> Result { + let parsed = query::parse(raw_query).map_err(MergeCliError::Query)?; + + let scan = vault::scan(vault_root); + if !scan.issues.is_empty() { + return Err(MergeCliError::Scan(scan.issues)); + } + + // The merge engine reads from a NoteStore exactly as the HTTP path does; + // a one-shot `replace` is the whole "index" this subcommand needs. + let store = NoteStore::new(); + store.replace(scan.notes); + + query::execute_merge(&store, &parsed) + .map_err(|MergeError::KindGuard(msg)| MergeCliError::Kind(msg)) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + use std::path::Path; + use tempfile::TempDir; + + fn write(root: &Path, rel: &str, body: &str) { + let p = root.join(rel); + if let Some(parent) = p.parent() { + fs::create_dir_all(parent).unwrap(); + } + fs::write(p, body).unwrap(); + } + + #[test] + fn merges_bodies_with_source_markers() { + let tmp = TempDir::new().unwrap(); + write(tmp.path(), "a.md", "---\nnum: 1\n---\nalpha\n"); + write(tmp.path(), "b.md", "---\nnum: 2\n---\nbeta\n"); + let out = run(tmp.path(), "").unwrap(); + // Body is frontmatter-stripped; fragments join with a blank line and + // there is no trailing newline -- byte-identical to the HTTP body. + assert_eq!( + out, + "\nalpha\n\n\n\nbeta\n" + ); + } + + #[test] + fn order_desc_then_path_tiebreak() { + let tmp = TempDir::new().unwrap(); + write(tmp.path(), "a.md", "---\nnum: 1\n---\nlow\n"); + write(tmp.path(), "b.md", "---\nnum: 3\n---\nhigh\n"); + write(tmp.path(), "c.md", "---\nnum: 2\n---\nmid\n"); + let out = run(tmp.path(), "__anw-order=num:desc").unwrap(); + let bodies: Vec<&str> = out + .lines() + .filter(|l| !l.starts_with("\nalpha\n\n\n\nbeta\n" - ); - } - - #[test] - fn order_desc_then_path_tiebreak() { - let tmp = TempDir::new().unwrap(); - write(tmp.path(), "a.md", "---\nnum: 1\n---\nlow\n"); - write(tmp.path(), "b.md", "---\nnum: 3\n---\nhigh\n"); - write(tmp.path(), "c.md", "---\nnum: 2\n---\nmid\n"); - let out = merge(tmp.path(), "__anw-order=num:desc").unwrap(); - let bodies: Vec<&str> = out - .lines() - .filter(|l| !l.starts_with("