diff --git a/.gitignore b/.gitignore index 89d8dfd2..0127fdc5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ run.sh _ignore .DS_Store +crates/registry/src/schema/*s.rs +crates/registry/src/schema/*impl.rs diff --git a/Cargo.lock b/Cargo.lock index e1e69a31..5f6ccabd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" @@ -185,9 +185,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.8.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5" +checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e" dependencies = [ "rustversion", ] @@ -224,11 +224,11 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii-canvas" -version = "4.0.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" dependencies = [ - "term 1.2.1", + "term", ] [[package]] @@ -243,7 +243,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", ] @@ -255,7 +255,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "synstructure", ] @@ -267,7 +267,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -337,7 +337,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -359,7 +359,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -370,7 +370,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -387,7 +387,7 @@ checksum = "07a9b245ba0739fc90935094c29adbaee3f977218b5fb95e822e261cda7f56a3" dependencies = [ "http 1.4.0", "log", - "rustls 0.23.36", + "rustls 0.23.35", "serde", "serde_json", "url", @@ -437,7 +437,7 @@ dependencies = [ "bytes", "dyn-clone", "futures", - "getrandom 0.2.17", + "getrandom 0.2.16", "hmac 0.12.1", "http-types", "once_cell", @@ -559,9 +559,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" [[package]] name = "bincode" @@ -609,7 +609,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -627,7 +627,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -646,15 +646,30 @@ dependencies = [ "serde_json", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec 0.6.3", +] + [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", ] +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bit-vec" version = "0.8.0" @@ -663,18 +678,18 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ "serde_core", ] [[package]] name = "bitpacking" -version = "0.9.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a7139abd3d9cebf8cd6f920a389cf3dc9576172e32f4563f188cae3c3eb019" +checksum = "4c1d3e2bfd8d06048a179f7b17afc3188effa10385e7b00dc65af6aae732ea92" dependencies = [ "crunchy", ] @@ -712,16 +727,15 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.3" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2468ef7d57b3fb7e16b576e8377cdbde2320c60e1491e961d11da40fc4f02a2d" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", - "constant_time_eq 0.4.2", - "cpufeatures", + "constant_time_eq", ] [[package]] @@ -816,14 +830,14 @@ checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "bytemuck" -version = "1.25.0" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -833,9 +847,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" dependencies = [ "serde", ] @@ -932,9 +946,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -1000,9 +1014,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.43" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", "js-sys", @@ -1056,9 +1070,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.58" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -1066,9 +1080,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.58" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -1078,21 +1092,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "clap_lex" -version = "1.0.0" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmac" @@ -1136,7 +1150,7 @@ dependencies = [ [[package]] name = "common" -version = "0.15.5" +version = "0.15.4" dependencies = [ "aes-gcm-siv", "ahash", @@ -1147,6 +1161,7 @@ dependencies = [ "calcard 0.3.2", "chrono", "compact_str", + "coordinator", "decancer", "directory", "dns-update", @@ -1157,7 +1172,7 @@ dependencies = [ "idna", "imagesize", "imap_proto", - "indexmap 2.13.0", + "indexmap 2.12.1", "infer 0.19.0", "jmap_proto", "libc", @@ -1188,7 +1203,7 @@ dependencies = [ "ring", "rkyv", "rsa", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -1270,7 +1285,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "once_cell", "tiny-keccak", ] @@ -1311,10 +1326,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" [[package]] -name = "constant_time_eq" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" +name = "coordinator" +version = "0.15.4" +dependencies = [ + "async-nats", + "futures", + "rdkafka", + "redis", + "store", + "tokio", + "trc", + "utils", + "zenoh", +] [[package]] name = "core-foundation" @@ -1545,7 +1569,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1579,7 +1603,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1593,7 +1617,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1604,7 +1628,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1615,7 +1639,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1626,13 +1650,13 @@ checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04" [[package]] name = "data-encoding" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "dav" -version = "0.15.5" +version = "0.15.4" dependencies = [ "calcard 0.3.2", "chrono", @@ -1654,7 +1678,7 @@ dependencies = [ [[package]] name = "dav-proto" -version = "0.15.5" +version = "0.15.4" dependencies = [ "calcard 0.3.2", "chrono", @@ -1711,7 +1735,7 @@ checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" dependencies = [ "async-trait", "deadpool 0.12.3", - "getrandom 0.2.17", + "getrandom 0.2.16", "tokio", "tokio-postgres", "tracing", @@ -1769,9 +1793,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.6" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", "serde_core", @@ -1785,7 +1809,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -1820,7 +1844,7 @@ dependencies = [ [[package]] name = "directory" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "argon2", @@ -1842,7 +1866,7 @@ dependencies = [ "regex", "reqwest", "rkyv", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "scrypt", "serde", @@ -1909,7 +1933,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2073,7 +2097,7 @@ dependencies = [ [[package]] name = "email" -version = "0.15.5" +version = "0.15.4" dependencies = [ "aes", "aes-gcm", @@ -2108,9 +2132,9 @@ dependencies = [ [[package]] name = "ena" -version = "0.14.4" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" dependencies = [ "log", ] @@ -2145,7 +2169,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2193,11 +2217,11 @@ dependencies = [ [[package]] name = "event_macro" -version = "0.15.5" +version = "0.15.4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2220,11 +2244,11 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fancy-regex" -version = "0.17.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8" +checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" dependencies = [ - "bit-set", + "bit-set 0.8.0", "regex-automata", "regex-syntax", ] @@ -2243,9 +2267,9 @@ checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" [[package]] name = "fastbloom" -version = "0.14.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" +checksum = "18c1ddb9231d8554c2d6bdf4cfaabf0c59251658c68b6c95cd52dd0c513a912a" dependencies = [ "getrandom 0.3.4", "libm", @@ -2286,9 +2310,15 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "fixedbitset" @@ -2298,14 +2328,14 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.9" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", + "libz-rs-sys", "libz-sys", "miniz_oxide", - "zlib-rs", ] [[package]] @@ -2365,7 +2395,7 @@ dependencies = [ "memchr", "mime", "serde", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -2417,7 +2447,7 @@ checksum = "c4ca5370149145ec3741cd7e82832f17f893b9421ee4e484d9511c6702bd9911" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "try_map", ] @@ -2518,7 +2548,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2595,9 +2625,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.17" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", @@ -2620,19 +2650,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", - "wasip3", -] - [[package]] name = "ghash" version = "0.5.1" @@ -2666,7 +2683,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2688,7 +2705,7 @@ dependencies = [ [[package]] name = "groupware" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "calcard 0.3.2", @@ -2719,7 +2736,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.13.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -2728,9 +2745,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -2738,7 +2755,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.13.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -2791,7 +2808,7 @@ checksum = "149e3ea90eb5a26ad354cfe3cb7f7401b9329032d0235f2687d03a35f30e5d4c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -2898,9 +2915,9 @@ dependencies = [ "once_cell", "rand 0.9.2", "ring", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", "tinyvec", "tokio", @@ -2924,9 +2941,9 @@ dependencies = [ "parking_lot", "rand 0.9.2", "resolv-conf", - "rustls 0.23.36", + "rustls 0.23.35", "smallvec", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-rustls 0.26.4", "tracing", @@ -2993,7 +3010,7 @@ dependencies = [ [[package]] name = "http" -version = "0.15.5" +version = "0.15.4" dependencies = [ "async-stream", "base64 0.22.1", @@ -3103,7 +3120,7 @@ dependencies = [ [[package]] name = "http_proto" -version = "0.15.5" +version = "0.15.4" dependencies = [ "common", "compact_str", @@ -3174,7 +3191,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2 0.4.13", + "h2 0.4.12", "http 1.4.0", "http-body 1.0.1", "httparse", @@ -3210,12 +3227,12 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "hyper-util", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", ] [[package]] @@ -3233,13 +3250,14 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.20" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", @@ -3248,7 +3266,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.2", + "socket2 0.6.1", "tokio", "tower-service", "tracing", @@ -3256,9 +3274,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.65" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3359,12 +3377,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "idea" version = "0.5.1" @@ -3409,7 +3421,7 @@ checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c" [[package]] name = "imap" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "common", @@ -3417,14 +3429,14 @@ dependencies = [ "directory", "email", "imap_proto", - "indexmap 2.13.0", + "indexmap 2.12.1", "mail-parser", "mail-send", "md5 0.8.0", "nlp", "parking_lot", "rand 0.9.2", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "store", "tokio", @@ -3436,7 +3448,7 @@ dependencies = [ [[package]] name = "imap_proto" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "chrono", @@ -3472,7 +3484,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "zstd", ] @@ -3499,9 +3511,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -3585,9 +3597,9 @@ dependencies = [ [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -3619,6 +3631,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -3639,9 +3660,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "jemalloc-sys" @@ -3688,7 +3709,7 @@ dependencies = [ [[package]] name = "jmap" -version = "0.15.5" +version = "0.15.4" dependencies = [ "aes-gcm", "aes-gcm-siv", @@ -3754,7 +3775,7 @@ dependencies = [ "maybe-async", "parking_lot", "reqwest", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "serde", "serde_json", @@ -3776,7 +3797,7 @@ dependencies = [ "maybe-async", "parking_lot", "reqwest", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "serde", "serde_json", @@ -3798,7 +3819,7 @@ dependencies = [ [[package]] name = "jmap_proto" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "calcard 0.3.2", @@ -3849,9 +3870,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -3870,9 +3891,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.6" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -3892,7 +3913,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee7893dab2e44ae5f9d0173f26ff4aa327c10b01b06a72b52dd9405b628640d" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", ] [[package]] @@ -3917,33 +3938,32 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.22.2" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", - "bit-set", + "bit-set 0.5.3", "ena", - "itertools 0.14.0", + "itertools 0.11.0", "lalrpop-util", - "petgraph 0.7.1", + "petgraph 0.6.5", "regex", "regex-syntax", - "sha3", "string_cache", - "term 1.2.1", + "term", + "tiny-keccak", "unicode-xid", "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.22.2" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ "regex-automata", - "rustversion", ] [[package]] @@ -3979,9 +3999,9 @@ dependencies = [ "log", "nom", "percent-encoding", - "rustls 0.23.36", - "rustls-native-certs 0.8.3", - "thiserror 2.0.18", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", + "thiserror 2.0.17", "tokio", "tokio-rustls 0.26.4", "tokio-stream", @@ -3990,12 +4010,6 @@ dependencies = [ "x509-parser", ] -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libbz2-rs-sys" version = "0.2.2" @@ -4004,9 +4018,9 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7" [[package]] name = "libc" -version = "0.2.182" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libflate" @@ -4044,18 +4058,19 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ "bitflags", "libc", + "redox_syscall 0.6.0", ] [[package]] @@ -4084,6 +4099,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-rs-sys" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" +dependencies = [ + "zlib-rs", +] + [[package]] name = "libz-sys" version = "1.1.23" @@ -4226,9 +4250,9 @@ dependencies = [ [[package]] name = "mail-parser" -version = "0.11.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82a3d6522697593ba4c683e0a6ee5a40fee93bc1a525e3cc6eeb3da11fd8897" +checksum = "dcf4390741c4e6fa330bdeccdfb580815dbb462952de91838b723357985119a3" dependencies = [ "encoding_rs", "hashify", @@ -4245,17 +4269,17 @@ dependencies = [ "base64 0.22.1", "gethostname", "md5 0.8.0", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "smtp-proto", "tokio", "tokio-rustls 0.26.4", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", ] [[package]] name = "managesieve" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "common", @@ -4270,7 +4294,7 @@ dependencies = [ "md5 0.8.0", "parking_lot", "rkyv", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "sieve-rs", "store", @@ -4304,7 +4328,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -4342,9 +4366,9 @@ checksum = "ae960838283323069879657ca3de837e9f7bbb4c7bf6ea7f1b290d5e9476d2e0" [[package]] name = "memchr" -version = "2.8.0" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memory-stats" @@ -4364,7 +4388,7 @@ checksum = "c797b9d6bb23aab2fc369c65f871be49214f5c759af65bde26ffaaa2b646b492" [[package]] name = "migration" -version = "0.15.5" +version = "0.15.4" dependencies = [ "base64 0.22.1", "bincode 1.3.3", @@ -4441,9 +4465,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.13" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac832c50ced444ef6be0767a008b02c106a909ba79d1d830501e94b96f6b7e" +checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -4473,7 +4497,7 @@ checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -4489,9 +4513,9 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "termcolor", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -4512,12 +4536,12 @@ dependencies = [ "pem", "percent-encoding", "rand 0.9.2", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "serde", "serde_json", "socket2 0.5.10", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-rustls 0.26.4", "tokio-util", @@ -4549,7 +4573,7 @@ dependencies = [ "serde_json", "sha1", "sha2 0.10.9", - "thiserror 2.0.18", + "thiserror 2.0.17", "uuid", ] @@ -4559,7 +4583,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", ] [[package]] @@ -4598,7 +4622,7 @@ dependencies = [ "data-encoding", "ed25519", "ed25519-dalek", - "getrandom 0.2.17", + "getrandom 0.2.16", "log", "rand 0.8.5", "signatory", @@ -4606,7 +4630,7 @@ dependencies = [ [[package]] name = "nlp" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "bincode 1.3.3", @@ -4710,9 +4734,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" @@ -4773,7 +4797,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -4782,24 +4806,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -[[package]] -name = "objc2-core-foundation" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" -dependencies = [ - "bitflags", -] - -[[package]] -name = "objc2-system-configuration" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7216bd11cbda54ccabcab84d523dc93b858ec75ecfb3a7d89513fa22464da396" -dependencies = [ - "objc2-core-foundation", -] - [[package]] name = "object" version = "0.37.3" @@ -4875,7 +4881,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -4884,12 +4890,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - [[package]] name = "openssl-sys" version = "0.9.111" @@ -4912,7 +4912,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -4944,7 +4944,7 @@ dependencies = [ "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tonic", "tracing", @@ -4982,7 +4982,7 @@ dependencies = [ "percent-encoding", "rand 0.9.2", "serde_json", - "thiserror 2.0.18", + "thiserror 2.0.17", "tracing", ] @@ -5064,7 +5064,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", "windows-link", ] @@ -5125,9 +5125,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.6" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" dependencies = [ "memchr", "ucd-trie", @@ -5135,9 +5135,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.6" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" dependencies = [ "pest", "pest_generator", @@ -5145,22 +5145,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.6" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "pest_meta" -version = "2.8.6" +version = "2.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" dependencies = [ "pest", "sha2 0.10.9", @@ -5168,12 +5168,12 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.7.1" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ - "fixedbitset", - "indexmap 2.13.0", + "fixedbitset 0.4.2", + "indexmap 2.12.1", ] [[package]] @@ -5182,9 +5182,9 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ - "fixedbitset", + "fixedbitset 0.5.7", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.12.1", "serde", ] @@ -5238,7 +5238,7 @@ dependencies = [ "phf_shared 0.13.1", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5285,7 +5285,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5373,7 +5373,7 @@ dependencies = [ [[package]] name = "pop3" -version = "0.15.5" +version = "0.15.4" dependencies = [ "common", "directory", @@ -5381,7 +5381,7 @@ dependencies = [ "imap", "mail-parser", "mail-send", - "rustls 0.23.36", + "rustls 0.23.35", "store", "tokio", "tokio-rustls 0.26.4", @@ -5392,15 +5392,15 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "postgres-protocol" -version = "0.6.10" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee9dd5fe15055d2b6806f4736aa0c9637217074e224bbec46d4041b91bb9491" +checksum = "fbef655056b916eb868048276cfd5d6a7dea4f81560dfd047f97c8c6fe3fcfd4" dependencies = [ "base64 0.22.1", "byteorder", @@ -5416,9 +5416,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.12" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b858f82211e84682fecd373f68e1ceae642d8d751a1ebd13f33de6257b3e20" +checksum = "ef4605b7c057056dd35baeb6ac0c0338e4975b1f2bef0f65da953285eb007095" dependencies = [ "bytes", "fallible-iterator 0.2.0", @@ -5444,9 +5444,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppmd-rust" -version = "1.4.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efca4c95a19a79d1c98f791f10aebd5c1363b473244630bb7dbde1dc98455a24" +checksum = "d558c559f0450f16f2a27a1f017ef38468c1090c9ce63c8e51366232d53717b4" [[package]] name = "ppv-lite86" @@ -5470,7 +5470,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5483,7 +5483,7 @@ dependencies = [ "encode_unicode", "is-terminal", "lazy_static", - "term 0.7.0", + "term", "unicode-width 0.1.14", ] @@ -5558,25 +5558,25 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "proc_macros" -version = "0.15.5" +version = "0.15.4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5590,7 +5590,7 @@ dependencies = [ "lazy_static", "memchr", "parking_lot", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -5613,7 +5613,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5628,9 +5628,9 @@ dependencies = [ [[package]] name = "psl" -version = "2.1.190" +version = "2.1.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fed3dc7578357ff12137c75eac73413b6aba9a7204916c19f2a0e9e1e920e0" +checksum = "5a72fc75a5577d37dc9e161f7ed3b27cda8091f254367370c988a41fe2683696" dependencies = [ "psl-types", ] @@ -5658,7 +5658,7 @@ checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -5735,9 +5735,9 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls 0.23.36", - "socket2 0.6.2", - "thiserror 2.0.18", + "rustls 0.23.35", + "socket2 0.6.1", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -5756,11 +5756,11 @@ dependencies = [ "rand 0.9.2", "ring", "rustc-hash 2.1.1", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "rustls-platform-verifier", "slab", - "thiserror 2.0.18", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -5775,16 +5775,16 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.2", + "socket2 0.6.1", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.44" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -5862,7 +5862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -5892,7 +5892,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.5", + "rand_core 0.9.3", ] [[package]] @@ -5910,14 +5910,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", ] [[package]] name = "rand_core" -version = "0.9.5" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.4", ] @@ -6021,9 +6021,9 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.14.7" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" +checksum = "3ec0a99f2de91c3cddc84b37e7db80e4d96b743e05607f647eb236fc0455907f" dependencies = [ "pem", "ring", @@ -6053,9 +6053,9 @@ dependencies = [ [[package]] name = "rdkafka-sys" -version = "4.10.0+2.12.1" +version = "4.9.0+2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e234cf318915c1059d4921ef7f75616b5219b10b46e9f3a511a15eb4b56a3f77" +checksum = "5230dca48bc354d718269f3e4353280e188b610f7af7e2fcf54b7a79d5802872" dependencies = [ "cmake", "libc", @@ -6082,16 +6082,16 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rand 0.9.2", - "rustls 0.23.36", - "rustls-native-certs 0.8.3", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", "ryu", "sha1_smol", - "socket2 0.6.2", + "socket2 0.6.1", "tokio", "tokio-rustls 0.26.4", "tokio-util", "url", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", ] [[package]] @@ -6103,13 +6103,22 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "libredox", "thiserror 1.0.69", ] @@ -6120,9 +6129,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "libredox", - "thiserror 2.0.18", + "thiserror 2.0.17", ] [[package]] @@ -6142,14 +6151,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -6159,9 +6168,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -6170,9 +6179,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "registry" +version = "0.15.4" +dependencies = [ + "hashify", + "serde", + "serde_json", + "trc", + "types", + "utils", +] [[package]] name = "rend" @@ -6194,7 +6215,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.13", + "h2 0.4.12", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -6207,7 +6228,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "serde", "serde_json", @@ -6216,7 +6237,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tokio-util", - "tower 0.5.3", + "tower 0.5.2", "tower-http", "tower-service", "url", @@ -6224,7 +6245,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", ] [[package]] @@ -6260,7 +6281,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.17", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -6287,14 +6308,14 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.15" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" dependencies = [ "bytecheck", "bytes", - "hashbrown 0.16.1", - "indexmap 2.13.0", + "hashbrown 0.15.5", + "indexmap 2.12.1", "munge", "ptr_meta", "rancor", @@ -6306,13 +6327,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.15" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -6368,9 +6389,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.10" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" dependencies = [ "const-oid", "digest 0.10.7", @@ -6475,9 +6496,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc-hash" @@ -6536,15 +6557,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.36" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.8", "subtle", "zeroize", ] @@ -6555,7 +6576,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ - "openssl-probe 0.1.6", + "openssl-probe", "rustls-pemfile 1.0.4", "schannel", "security-framework 2.11.1", @@ -6567,7 +6588,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ - "openssl-probe 0.1.6", + "openssl-probe", "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", @@ -6576,14 +6597,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ - "openssl-probe 0.2.1", + "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.6.0", + "security-framework 3.5.1", ] [[package]] @@ -6606,9 +6627,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -6625,11 +6646,11 @@ dependencies = [ "jni", "log", "once_cell", - "rustls 0.23.36", - "rustls-native-certs 0.8.3", + "rustls 0.23.35", + "rustls-native-certs 0.8.2", "rustls-platform-verifier-android", - "rustls-webpki 0.103.9", - "security-framework 3.6.0", + "rustls-webpki 0.103.8", + "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs", "windows-sys 0.61.2", @@ -6663,9 +6684,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -6680,9 +6701,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.23" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" [[package]] name = "salsa20" @@ -6749,9 +6770,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "either", @@ -6763,14 +6784,14 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.2.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d115b50f4aaeea07e79c1912f645c7513d81715d0420f8bc77a18c6260b307f" +checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -6846,9 +6867,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.6.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation 0.10.1", @@ -6859,9 +6880,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.16.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -6875,9 +6896,9 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "sequoia-openpgp" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0620e44a7d514adf7df87b44db235f13b81fed7ddc265adb26f014d42626ac47" +checksum = "f0e334ce3ec5b9b47d86a80563b3ecec435f59acf37e86058b3b686a42c5a2ba" dependencies = [ "aes", "aes-gcm", @@ -6902,7 +6923,7 @@ dependencies = [ "ecdsa", "ed25519", "ed25519-dalek", - "getrandom 0.2.17", + "getrandom 0.2.16", "hkdf", "idea", "idna", @@ -6916,7 +6937,7 @@ dependencies = [ "p256", "p384", "p521", - "rand 0.9.2", + "rand 0.8.5", "rand_core 0.6.4", "regex", "regex-syntax", @@ -6925,7 +6946,7 @@ dependencies = [ "sha1collisiondetection", "sha2 0.10.9", "sha3", - "thiserror 2.0.18", + "thiserror 2.0.17", "twofish", "typenum", "x25519-dalek", @@ -6969,7 +6990,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -6980,16 +7001,16 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "itoa", "memchr", "serde", @@ -7025,7 +7046,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -7050,9 +7071,9 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.12.1", "schemars 0.9.0", - "schemars 1.2.1", + "schemars 1.1.0", "serde_core", "serde_json", "serde_with_macros", @@ -7068,7 +7089,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -7077,7 +7098,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "itoa", "ryu", "serde", @@ -7086,12 +7107,11 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d0b343e184fc3b7bb44dff0705fffcf4b3756ba6aff420dddd8b24ca145e555" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ - "futures-executor", - "futures-util", + "futures", "log", "once_cell", "parking_lot", @@ -7101,18 +7121,18 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.3.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f50427f258fb77356e4cd4aa0e87e2bd2c66dbcee41dc405282cae2bfc26c83" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "services" -version = "0.15.5" +version = "0.15.4" dependencies = [ "aes-gcm", "aes-gcm-siv", @@ -7252,9 +7272,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "sieve-rs" -version = "0.7.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37baebe7a22af73f881c1856c620680444f6ea99482a7734a13f7fc570d17028" +checksum = "9ada516ead6adf4f915e69fcb123640bcf23a9b29fc4b537145487e91af7a594" dependencies = [ "ahash", "arc-swap", @@ -7268,11 +7288,10 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.8" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ - "errno", "libc", ] @@ -7312,15 +7331,15 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "slab" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" @@ -7330,7 +7349,7 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "smtp" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "blake3", @@ -7357,7 +7376,7 @@ dependencies = [ "regex", "reqwest", "rkyv", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -7373,7 +7392,7 @@ dependencies = [ "trc", "types", "utils", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", "x509-parser", ] @@ -7422,9 +7441,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", "windows-sys 0.60.2", @@ -7432,7 +7451,7 @@ dependencies = [ [[package]] name = "spam-filter" -version = "0.15.5" +version = "0.15.4" dependencies = [ "common", "compact_str", @@ -7530,14 +7549,15 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "stalwart" -version = "0.15.5" +version = "0.15.4" dependencies = [ "common", + "coordinator", "dav", "directory", "email", "groupware", - "http 0.15.5", + "http 0.15.4", "imap", "jemallocator", "jmap", @@ -7556,7 +7576,7 @@ dependencies = [ [[package]] name = "stalwart-cli" -version = "0.15.5" +version = "0.15.4" dependencies = [ "clap", "console", @@ -7587,11 +7607,10 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "store" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "arc-swap", - "async-nats", "azure_core", "azure_storage", "azure_storage_blobs", @@ -7615,9 +7634,9 @@ dependencies = [ "r2d2", "rand 0.9.2", "rayon", - "rdkafka", "redis", "regex", + "registry", "reqwest", "ring", "rkyv", @@ -7626,7 +7645,7 @@ dependencies = [ "rusqlite", "rust-s3", "rustls 0.21.12", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "serde", "serde_json", @@ -7637,7 +7656,6 @@ dependencies = [ "types", "utils", "xxhash-rust", - "zenoh", ] [[package]] @@ -7688,9 +7706,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.115" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e614ed320ac28113fa64972c4262d5dbc89deacdfd00c34a3e4cea073243c12" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -7714,7 +7732,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -7740,15 +7758,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "term" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -7760,7 +7769,7 @@ dependencies = [ [[package]] name = "tests" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "async-trait", @@ -7771,6 +7780,7 @@ dependencies = [ "chrono", "common", "compact_str", + "coordinator", "csv", "dav", "dav-proto", @@ -7781,7 +7791,7 @@ dependencies = [ "form_urlencoded", "futures", "groupware", - "http 0.15.5", + "http 0.15.4", "http-body-util", "http_proto", "hyper 1.8.1", @@ -7806,7 +7816,7 @@ dependencies = [ "reqwest", "ring", "rkyv", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -7836,11 +7846,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.18", + "thiserror-impl 2.0.17", ] [[package]] @@ -7851,18 +7861,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -7876,31 +7886,31 @@ dependencies = [ [[package]] name = "time" -version = "0.3.47" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", "js-sys", "num-conv", "powerfmt", - "serde_core", + "serde", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -7948,7 +7958,7 @@ checksum = "1461056cc1ef47003f7ee16e4cef3741068d4c7f6b627bfce49b7c00c120a530" dependencies = [ "futures-util", "pin-project-lite", - "thiserror 2.0.18", + "thiserror 2.0.17", "tokio", "tokio-rustls 0.26.4", ] @@ -7966,9 +7976,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.49.0" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ "bytes", "libc", @@ -7976,7 +7986,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.2", + "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", ] @@ -7989,14 +7999,14 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "tokio-postgres" -version = "0.7.16" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcea47c8f71744367793f16c2db1f11cb859d28f436bdb4ca9193eb1f787ee42" +checksum = "2b40d66d9b2cfe04b628173409368e58247e8eddbbd3b0e6c6ba1d09f20f6c9e" dependencies = [ "async-trait", "byteorder", @@ -8012,7 +8022,7 @@ dependencies = [ "postgres-protocol", "postgres-types", "rand 0.9.2", - "socket2 0.6.2", + "socket2 0.6.1", "tokio", "tokio-util", "whoami", @@ -8034,15 +8044,15 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.36", + "rustls 0.23.35", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" dependencies = [ "futures-core", "pin-project-lite", @@ -8057,7 +8067,7 @@ checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", @@ -8067,9 +8077,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -8115,7 +8125,7 @@ version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.12.1", "toml_datetime", "toml_parser", "winnow", @@ -8123,9 +8133,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.8+spec-1.1.0" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0742ff5ff03ea7e67c8ae6c93cac239e0d9784833362da3f9a9c1da8dfefcbdc" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] @@ -8166,7 +8176,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f124352108f58ef88299e909f6e9470f1cdc8d2a1397963901b4a6366206bf72" dependencies = [ "base32", - "constant_time_eq 0.3.1", + "constant_time_eq", "hmac 0.12.1", "sha1", "sha2 0.10.9", @@ -8196,9 +8206,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", @@ -8222,7 +8232,7 @@ dependencies = [ "http-body 1.0.1", "iri-string", "pin-project-lite", - "tower 0.5.3", + "tower 0.5.2", "tower-layer", "tower-service", ] @@ -8259,7 +8269,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -8316,7 +8326,7 @@ dependencies = [ [[package]] name = "trc" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "base64 0.22.1", @@ -8367,10 +8377,10 @@ dependencies = [ "httparse", "log", "rand 0.9.2", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pki-types", "sha1", - "thiserror 2.0.18", + "thiserror 2.0.17", "utf-8", ] @@ -8403,7 +8413,7 @@ checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "types" -version = "0.15.5" +version = "0.15.4" dependencies = [ "blake3", "compact_str", @@ -8452,9 +8462,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.9.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-bidi" @@ -8470,9 +8480,9 @@ checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-normalization" @@ -8559,20 +8569,19 @@ checksum = "3b5bb2756c16fb66f80cfbf5fb0e0c09a7001e739f453c9ec241b9c8b1556fda" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] name = "url" -version = "2.5.8" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", - "serde_derive", ] [[package]] @@ -8601,7 +8610,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utils" -version = "0.15.5" +version = "0.15.4" dependencies = [ "ahash", "base64 0.22.1", @@ -8622,12 +8631,12 @@ dependencies = [ "psl", "quick_cache", "rand 0.9.2", - "rcgen 0.14.7", + "rcgen 0.14.6", "regex", "reqwest", "ring", "rkyv", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", @@ -8636,18 +8645,18 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "trc", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", "x509-parser", "xxhash-rust", ] [[package]] name = "uuid" -version = "1.21.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.3.4", "js-sys", "serde_core", "sha1_smol", @@ -8674,7 +8683,7 @@ checksum = "8c44ce98e7227a04eeb4cf9c784109a5c9710e54849ceb4f09f8597247897f1e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "unzip-n", ] @@ -8745,47 +8754,26 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasite" -version = "1.0.2" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fe902b4a6b8028a753d5424909b764ccf79b7a209eac9bf97e59cda9f71a42" -dependencies = [ - "wasi 0.14.7+wasi-0.2.4", -] +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -8796,12 +8784,11 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", - "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -8810,9 +8797,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8820,48 +8807,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.13.0", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.4.2" @@ -8875,23 +8840,11 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver", -] - [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -8909,9 +8862,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" dependencies = [ "rustls-pki-types", ] @@ -8922,14 +8875,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", ] [[package]] name = "webpki-roots" -version = "1.0.6" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -8945,13 +8898,11 @@ dependencies = [ [[package]] name = "whoami" -version = "2.1.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a5b12f9df4f978d2cfdb1bd3bac52433f44393342d7ee9c25f5a1c14c0f45d" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "libc", "libredox", - "objc2-system-configuration", "wasite", "web-sys", ] @@ -9014,7 +8965,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -9025,7 +8976,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -9370,91 +9321,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck 0.5.0", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck 0.5.0", - "indexmap 2.13.0", - "prettyplease", - "syn 2.0.115", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.115", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap 2.13.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.13.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -9484,9 +9353,9 @@ dependencies = [ [[package]] name = "x509-parser" -version = "0.18.1" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43b0f71ce057da06bc0851b23ee24f3f86190b07203dd8f567d0b706a185202" +checksum = "eb3e137310115a65136898d2079f003ce33331a6c4b0d51f1531d1be082b6425" dependencies = [ "asn1-rs", "data-encoding", @@ -9496,7 +9365,7 @@ dependencies = [ "oid-registry", "ring", "rusticata-macros", - "thiserror 2.0.18", + "thiserror 2.0.17", "time", ] @@ -9540,15 +9409,15 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "synstructure", ] [[package]] name = "zenoh" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9ff8cb89f5267b8486a69466bc42f240f1ee2d5089e72395a23094e7b74f21" +checksum = "4e2df46d36ba8d173f18e9cce5011117fed81a90a22bc3cfe8bbcfaf66b54114" dependencies = [ "ahash", "arc-swap", @@ -9598,18 +9467,18 @@ dependencies = [ [[package]] name = "zenoh-buffers" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9216c3d6c84b56f3e3be634e52365022038e1ac1b9f662f10d425cbf6c0fa8" +checksum = "82d610eaa2099c16844b092c2b16605d115f354e332eb1d37e9af46e5430ecac" dependencies = [ "zenoh-collections", ] [[package]] name = "zenoh-codec" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14bc6747664aa9ecf17becd6e9a29282e535a350cd7c6bd8de7bf2dc662fb93d" +checksum = "7f1cff28c30bca3d07e7b84f71f1c9b81d505449f6fec36a023cc8b601c01150" dependencies = [ "tracing", "uhlc", @@ -9619,18 +9488,18 @@ dependencies = [ [[package]] name = "zenoh-collections" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d642ecfe0d85f0cd846be9bc92805d926c092a6e6c7a575b6346752f8c3ae16" +checksum = "a72cac7d4bbe99e41ef46c175e0dd2933e883b17cef3e60151e4461b5a088ad3" dependencies = [ "ahash", ] [[package]] name = "zenoh-config" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39765a5f9975aba204c99f2f65308db4952dbea8e5ac79c78ac1eaf5711e970a" +checksum = "df65e4ab337079d897aaaa6d01474b4f8683daaa05a8671b18db34e71a872af7" dependencies = [ "json5", "nonempty-collections", @@ -9653,9 +9522,9 @@ dependencies = [ [[package]] name = "zenoh-core" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c0c1388dccf287aec4e9d5e638630dc9d536db9f1da3522889b42697723b9b" +checksum = "869deb22305e8f7a6aa324142ab6717f0cc979be8e4a2de646e8f31313224a1c" dependencies = [ "lazy_static", "tokio", @@ -9665,9 +9534,9 @@ dependencies = [ [[package]] name = "zenoh-crypto" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b433e08df3b03f2af2d23bd29a32aa5f5522c52e66d63e3d135bfa66373736dd" +checksum = "7f5b09559108c9e11128730d5a6f551dbcc226adfd82423439ad7eeed024c736" dependencies = [ "aes", "hmac 0.12.1", @@ -9679,15 +9548,15 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a3c47c89cb55ea45a1b3fe7d1fe8682ea93530b1fc5245257812db14b55b3d" +checksum = "b8b754ea6460c4c3c5dd67e6a8c62bfc076c16f8b794898fb3ea6f0039a5939e" dependencies = [ - "getrandom 0.2.17", + "getrandom 0.2.16", "hashbrown 0.16.1", "keyed-set", "rand 0.8.5", - "schemars 1.2.1", + "schemars 1.1.0", "serde", "token-cell", "zenoh-result", @@ -9695,9 +9564,9 @@ dependencies = [ [[package]] name = "zenoh-link" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6218cecab58435f31fb8b2e185f74f35af8aedd96e8bdd3557b333206b1acfda" +checksum = "0d0c04d554b67600967cb520061ef9f635caf7704978357334e66cd7179a204a" dependencies = [ "zenoh-config", "zenoh-link-commons", @@ -9711,19 +9580,19 @@ dependencies = [ [[package]] name = "zenoh-link-commons" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98adc618f7edb570b9333ce583934a7c63e3a619cb49666515bfc06a000d7b6" +checksum = "52d1c652a706da1da46eae54a65c4b658153cdebfa213f061beea3bef71088f2" dependencies = [ "async-trait", "base64 0.22.1", "flume", "futures", "quinn", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.8", "secrecy", "serde", "socket2 0.5.10", @@ -9731,7 +9600,7 @@ dependencies = [ "tokio", "tokio-util", "tracing", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", "x509-parser", "zenoh-buffers", "zenoh-codec", @@ -9745,22 +9614,22 @@ dependencies = [ [[package]] name = "zenoh-link-quic" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d0c25d681db958b7714370d5e1d72a523129633d9262b098e18d44824d39893" +checksum = "0069d889388d06e56eb86139021a1af12b9846222847aeabaa05eb92fc2ee108" dependencies = [ "async-trait", "base64 0.22.1", "quinn", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.8", "secrecy", "time", "tokio", "tokio-util", "tracing", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -9771,9 +9640,9 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f23bd5d06a0014ce5a205961d6d47c8e8d792d9fd050ae9d0c9b609a187995" +checksum = "279ff42ab4a65508069596045ab8a3c6fb03f94343c290a9b75f9568c49094e4" dependencies = [ "async-trait", "socket2 0.5.10", @@ -9789,16 +9658,16 @@ dependencies = [ [[package]] name = "zenoh-link-tls" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17544cde682dbcd2a712114786feee14295c28a9f66fc1021637355511e32fa9" +checksum = "d3172615126b64456beb0c537351eb9c715f20f641e37ae8f84cb209816d205a" dependencies = [ "async-trait", "base64 0.22.1", - "rustls 0.23.36", + "rustls 0.23.35", "rustls-pemfile 2.2.0", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki 0.103.8", "secrecy", "socket2 0.5.10", "time", @@ -9807,7 +9676,7 @@ dependencies = [ "tokio-rustls 0.26.4", "tokio-util", "tracing", - "webpki-roots 1.0.6", + "webpki-roots 1.0.4", "x509-parser", "zenoh-config", "zenoh-core", @@ -9819,9 +9688,9 @@ dependencies = [ [[package]] name = "zenoh-link-udp" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "587ca1de1caa0b444106d31c26801f4e87b354293d2d37afd8f70d9e793fe35e" +checksum = "11006545a887167d431e8c3f2867ad386e7d678ee8babd3df4a7537b168e47de" dependencies = [ "async-trait", "libc", @@ -9841,21 +9710,21 @@ dependencies = [ [[package]] name = "zenoh-macros" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b760a458cd906ac888b37fd1abdb21a0f58ecc64cc3882f83a976cb5ca8e0632" +checksum = "21df1681ca014a4bd69db91d356bcf699d346f854ff8a6b73123cee75f5073cd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7325b773c43a86a94f800cb971ab7e4b7e01ce76819c9c100ea783a47c3a25e4" +checksum = "4651bc51951eb004e71bba71583f9ea60240bdd11351b61dbd6956e906088567" dependencies = [ "git-version", "libloading", @@ -9871,9 +9740,9 @@ dependencies = [ [[package]] name = "zenoh-protocol" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4d3dad7aeeea780495692b195cd56515569c32b76b9dd077cc408c3ebca03f" +checksum = "ab17d39b24f6fbd0a24e03a5ab96c236d3d5ebb5071978338c9bc3fe1ccff626" dependencies = [ "const_format", "rand 0.8.5", @@ -9886,18 +9755,18 @@ dependencies = [ [[package]] name = "zenoh-result" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b4dbfea68b947a790d5525bcf061e91e2fdc2798bce619851919b353a8580fa" +checksum = "1b7d23a2f69c4b96ae95ac2f80808cce5f2ed9697ba37e769a75428fb6806a57" dependencies = [ "anyhow", ] [[package]] name = "zenoh-runtime" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760a1f7880f98427ad849d600257d1455a18afe981681f362684a3f91042537e" +checksum = "a71f356bb63c1c9d37cb4bc89112e83a9fd6079458d1440232d67ca41a52c687" dependencies = [ "lazy_static", "ron", @@ -9910,9 +9779,9 @@ dependencies = [ [[package]] name = "zenoh-sync" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f132137bb003f10b7fff086cb18addf8e8273b9c0d2722a53b5074c8a79965" +checksum = "e3b1113111e247d6b1ebd5d406b43e23e78faca2c7525dca22a2a075c64787bd" dependencies = [ "arc-swap", "event-listener 5.4.1", @@ -9925,9 +9794,9 @@ dependencies = [ [[package]] name = "zenoh-task" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b17d10136fdabec7e21a3fcef568c210ee6a2d71cde6adcde99e9236584f3a1" +checksum = "7a1f690f81704b1e934b9fb7a63ce544af73521ca9d11b5a439cdfc74108dd28" dependencies = [ "futures", "tokio", @@ -9939,9 +9808,9 @@ dependencies = [ [[package]] name = "zenoh-transport" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50739b4c45e0963df8377abddb74701a4b708b178590eae92f27a604e25daf44" +checksum = "41cdc4dcb4a68161afe25e44871a66a5c3c347d86a77628ab101d859a9518db9" dependencies = [ "async-trait", "crossbeam-utils", @@ -9973,9 +9842,9 @@ dependencies = [ [[package]] name = "zenoh-util" -version = "1.7.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9512987c13925d32d3331507c8807853d5b682ea8da94d0ba6534c7a8ace48aa" +checksum = "ea9b52e8beceffc0deca01e10ca726c604286a1ac475f95acdd87ee55f18b120" dependencies = [ "async-trait", "const_format", @@ -9986,7 +9855,7 @@ dependencies = [ "libc", "libloading", "pnet_datalink", - "schemars 1.2.1", + "schemars 1.1.0", "serde", "serde_json", "shellexpand", @@ -10000,22 +9869,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -10035,7 +9904,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", "synstructure", ] @@ -10050,13 +9919,13 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -10089,7 +9958,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 2.0.111", ] [[package]] @@ -10101,13 +9970,13 @@ dependencies = [ "aes", "arbitrary", "bzip2", - "constant_time_eq 0.3.1", + "constant_time_eq", "crc32fast", "deflate64", "flate2", "getrandom 0.3.4", "hmac 0.12.1", - "indexmap 2.13.0", + "indexmap 2.12.1", "lzma-rust2", "memchr", "pbkdf2", @@ -10121,15 +9990,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.6.0" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7948af682ccbc3342b6e9420e8c51c1fe5d7bf7756002b4a3c6cabfe96a7e3c" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" [[package]] name = "zmij" -version = "1.0.21" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "f1dccf46b25b205e4bebe1d5258a991df1cc17801017a845cb5b3fe0269781aa" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index 916a24cf..0538c0ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,9 @@ members = [ "crates/spam-filter", "crates/nlp", "crates/store", + "crates/coordinator", "crates/directory", + "crates/registry", "crates/services", "crates/utils", "crates/common", diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 299fda92..e9d97ded 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -10,6 +10,7 @@ nlp = { path = "../nlp" } store = { path = "../store" } trc = { path = "../trc" } directory = { path = "../directory" } +coordinator = { path = "../coordinator" } types = { path = "../types" } jmap_proto = { path = "../jmap-proto" } imap_proto = { path = "../imap-proto" } diff --git a/crates/common/src/config/mod.rs b/crates/common/src/config/mod.rs index 533e8132..61147eee 100644 --- a/crates/common/src/config/mod.rs +++ b/crates/common/src/config/mod.rs @@ -13,6 +13,7 @@ use crate::{ listener::tls::AcmeProviders, manager::config::ConfigManager, }; use arc_swap::ArcSwap; +use coordinator::Coordinator; use directory::{Directories, Directory}; use groupware::GroupwareConfig; use hyper::HeaderMap; @@ -132,21 +133,21 @@ impl Core { } }) .unwrap_or_default(); - let pubsub = config - .value("cluster.coordinator") - .map(|id| id.to_string()) - .and_then(|id| { - if let Some(store) = stores.pubsub_stores.get(&id) { - store.clone().into() - } else { - config.new_parse_error( - "cluster.coordinator", - format!("Coordinator backend {id:?} not found"), - ); - None - } - }) - .unwrap_or_default(); + let pubsub = Coordinator::None; /*config + .value("cluster.coordinator") + .map(|id| id.to_string()) + .and_then(|id| { + if let Some(store) = stores.pubsub_stores.get(&id) { + store.clone().into() + } else { + config.new_parse_error( + "cluster.coordinator", + format!("Coordinator backend {id:?} not found"), + ); + None + } + }) + .unwrap_or_default();*/ let mut directories = Directories::parse(config, &stores, data.clone(), is_enterprise).await; let directory = config diff --git a/crates/common/src/config/storage.rs b/crates/common/src/config/storage.rs index 9d2feeb4..282c5df4 100644 --- a/crates/common/src/config/storage.rs +++ b/crates/common/src/config/storage.rs @@ -4,11 +4,11 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use std::sync::Arc; - use ahash::AHashMap; +use coordinator::Coordinator; use directory::Directory; -use store::{BlobStore, SearchStore, InMemoryStore, PubSubStore, PurgeSchedule, Store}; +use std::sync::Arc; +use store::{BlobStore, InMemoryStore, PurgeSchedule, SearchStore, Store}; use crate::manager::config::ConfigManager; @@ -18,7 +18,7 @@ pub struct Storage { pub blob: BlobStore, pub fts: SearchStore, pub lookup: InMemoryStore, - pub pubsub: PubSubStore, + pub pubsub: Coordinator, pub directory: Arc, pub directories: AHashMap>, pub purge_schedules: Vec, diff --git a/crates/common/src/manager/reload.rs b/crates/common/src/manager/reload.rs index f7692d2f..bcc3df7f 100644 --- a/crates/common/src/manager/reload.rs +++ b/crates/common/src/manager/reload.rs @@ -76,7 +76,6 @@ impl Server { blob_stores: self.core.storage.blobs.clone(), search_stores: self.core.storage.ftss.clone(), in_memory_stores: self.core.storage.lookups.clone(), - pubsub_stores: Default::default(), purge_schedules: Default::default(), }; stores.parse_stores(&mut config).await; diff --git a/crates/coordinator/Cargo.toml b/crates/coordinator/Cargo.toml new file mode 100644 index 00000000..1b14ddd7 --- /dev/null +++ b/crates/coordinator/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "coordinator" +version = "0.15.4" +edition = "2024" + +[dependencies] +utils = { path = "../utils" } +store = { path = "../store" } +trc = { path = "../trc" } +futures = { version = "0.3", optional = true } +tokio = { version = "1.47", features = ["sync", "fs", "io-util"] } +async-nats = { version = "0.44", default-features = false, features = ["server_2_10", "server_2_11", "ring"], optional = true } +zenoh = { version = "1.3.4", default-features = false, features = ["auth_pubkey", "transport_multilink", "transport_compression", "transport_quic", "transport_tcp", "transport_tls", "transport_udp"], optional = true } +rdkafka = { version = "0.38", features = ["cmake-build"], optional = true } +redis = { version = "0.32", features = [ "tokio-comp", "tokio-rustls-comp", "tls-rustls-insecure", "tls-rustls-webpki-roots", "cluster-async"], optional = true } + +[features] +nats = ["async-nats"] +zenoh = ["dep:zenoh"] +kafka = ["rdkafka"] +redis = ["dep:redis", "futures"] +enterprise = [] +test_mode = [] diff --git a/crates/store/src/backend/kafka/mod.rs b/crates/coordinator/src/backend/kafka/mod.rs similarity index 100% rename from crates/store/src/backend/kafka/mod.rs rename to crates/coordinator/src/backend/kafka/mod.rs diff --git a/crates/store/src/backend/kafka/pubsub.rs b/crates/coordinator/src/backend/kafka/pubsub.rs similarity index 100% rename from crates/store/src/backend/kafka/pubsub.rs rename to crates/coordinator/src/backend/kafka/pubsub.rs diff --git a/crates/coordinator/src/backend/mod.rs b/crates/coordinator/src/backend/mod.rs new file mode 100644 index 00000000..d384cf2d --- /dev/null +++ b/crates/coordinator/src/backend/mod.rs @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +#[cfg(feature = "kafka")] +pub mod kafka; +#[cfg(feature = "nats")] +pub mod nats; +#[cfg(feature = "redis")] +pub mod redis; +#[cfg(feature = "zenoh")] +pub mod zenoh; diff --git a/crates/store/src/backend/nats/mod.rs b/crates/coordinator/src/backend/nats/mod.rs similarity index 100% rename from crates/store/src/backend/nats/mod.rs rename to crates/coordinator/src/backend/nats/mod.rs diff --git a/crates/store/src/backend/nats/pubsub.rs b/crates/coordinator/src/backend/nats/pubsub.rs similarity index 100% rename from crates/store/src/backend/nats/pubsub.rs rename to crates/coordinator/src/backend/nats/pubsub.rs diff --git a/crates/coordinator/src/backend/redis/mod.rs b/crates/coordinator/src/backend/redis/mod.rs new file mode 100644 index 00000000..ec5e9322 --- /dev/null +++ b/crates/coordinator/src/backend/redis/mod.rs @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use crate::{Msg, PubSubStream}; +use futures::StreamExt; +use redis::{AsyncCommands, PushInfo, cluster::ClusterConfig, cluster_async::ClusterConnection}; +use std::fmt::Display; +use store::backend::redis::{RedisPool, RedisStore}; +use tokio::sync::mpsc::UnboundedReceiver; + +pub struct RedisPubSubStream { + stream: redis::aio::PubSubStream, +} + +pub struct RedisClusterPubSubStream { + _conn: ClusterConnection, + rx: UnboundedReceiver, +} + +pub(crate) async fn redis_publish( + redis: &RedisStore, + topic: &'static str, + message: Vec, +) -> trc::Result<()> { + match &redis.pool { + RedisPool::Single(pool) => pool + .get() + .await + .map_err(into_error)? + .as_mut() + .publish(topic, message) + .await + .map_err(into_error), + RedisPool::Cluster(pool) => pool + .get() + .await + .map_err(into_error)? + .as_mut() + .publish(topic, message) + .await + .map_err(into_error), + } +} + +pub(crate) async fn redis_subscribe( + redis: &RedisStore, + topic: &'static str, +) -> trc::Result { + match &redis.pool { + RedisPool::Single(pool) => { + let mut pubsub = pool + .manager() + .client + .get_async_pubsub() + .await + .map_err(into_error)?; + pubsub.subscribe(topic).await.map_err(into_error)?; + + Ok(PubSubStream::Redis(RedisPubSubStream { + stream: pubsub.into_on_message(), + })) + } + RedisPool::Cluster(pool) => { + let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); + + let mut _conn = pool + .manager() + .client + .get_async_connection_with_config(ClusterConfig::default().set_push_sender(tx)) + .await + .map_err(into_error)?; + + _conn.subscribe(topic).await.map_err(into_error)?; + + Ok(PubSubStream::RedisCluster(RedisClusterPubSubStream { + _conn, + rx, + })) + } + } +} + +impl RedisPubSubStream { + pub async fn next(&mut self) -> Option { + self.stream.next().await.map(Msg::Redis) + } +} + +impl RedisClusterPubSubStream { + pub async fn next(&mut self) -> Option { + loop { + if let Some(msg) = redis::Msg::from_push_info(self.rx.recv().await?) { + return Some(Msg::Redis(msg)); + } + } + } +} + +#[inline(always)] +fn into_error(err: impl Display) -> trc::Error { + trc::StoreEvent::RedisError.reason(err) +} diff --git a/crates/store/src/backend/zenoh/mod.rs b/crates/coordinator/src/backend/zenoh/mod.rs similarity index 100% rename from crates/store/src/backend/zenoh/mod.rs rename to crates/coordinator/src/backend/zenoh/mod.rs diff --git a/crates/store/src/backend/zenoh/pubsub.rs b/crates/coordinator/src/backend/zenoh/pubsub.rs similarity index 100% rename from crates/store/src/backend/zenoh/pubsub.rs rename to crates/coordinator/src/backend/zenoh/pubsub.rs diff --git a/crates/store/src/dispatch/pubsub.rs b/crates/coordinator/src/dispatch.rs similarity index 61% rename from crates/store/src/dispatch/pubsub.rs rename to crates/coordinator/src/dispatch.rs index b6363b46..89b1ff51 100644 --- a/crates/store/src/dispatch/pubsub.rs +++ b/crates/coordinator/src/dispatch.rs @@ -4,68 +4,44 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use crate::PubSubStore; - -pub enum PubSubStream { - #[cfg(feature = "redis")] - Redis(crate::backend::redis::pubsub::RedisPubSubStream), - #[cfg(feature = "redis")] - RedisCluster(crate::backend::redis::pubsub::RedisClusterPubSubStream), - #[cfg(feature = "nats")] - Nats(crate::backend::nats::pubsub::NatsPubSubStream), - #[cfg(feature = "zenoh")] - Zenoh(crate::backend::zenoh::pubsub::ZenohPubSubStream), - #[cfg(feature = "kafka")] - Kafka(crate::backend::kafka::pubsub::KafkaPubSubStream), - #[cfg(not(any(feature = "redis", feature = "nats")))] - Unimplemented, -} - -pub enum Msg { - #[cfg(feature = "redis")] - Redis(redis::Msg), - #[cfg(feature = "nats")] - Nats(async_nats::Message), - #[cfg(feature = "zenoh")] - Zenoh(Vec), - #[cfg(feature = "kafka")] - Kafka(Vec), - #[cfg(not(any(feature = "redis", feature = "nats")))] - Unimplemented, -} +#[cfg(feature = "redis")] +use crate::PubSubStream; +use crate::{Coordinator, Msg}; #[allow(unused_variables)] -impl PubSubStore { +impl Coordinator { pub async fn publish(&self, topic: &'static str, message: Vec) -> trc::Result<()> { match self { #[cfg(feature = "redis")] - PubSubStore::Redis(store) => store.publish(topic, message).await, + Coordinator::Redis(store) => { + crate::backend::redis::redis_publish(store, topic, message).await + } #[cfg(feature = "nats")] - PubSubStore::Nats(store) => store.publish(topic, message).await, + Coordinator::Nats(store) => store.publish(topic, message).await, #[cfg(feature = "zenoh")] - PubSubStore::Zenoh(store) => store.publish(topic, message).await, + Coordinator::Zenoh(store) => store.publish(topic, message).await, #[cfg(feature = "kafka")] - PubSubStore::Kafka(store) => store.publish(topic, message).await, - PubSubStore::None => Err(trc::StoreEvent::NotSupported.into_err()), + Coordinator::Kafka(store) => store.publish(topic, message).await, + Coordinator::None => Err(trc::StoreEvent::NotSupported.into_err()), } } pub async fn subscribe(&self, topic: &'static str) -> trc::Result { match self { #[cfg(feature = "redis")] - PubSubStore::Redis(store) => store.subscribe(topic).await, + Coordinator::Redis(store) => crate::backend::redis::redis_subscribe(store, topic).await, #[cfg(feature = "nats")] - PubSubStore::Nats(store) => store.subscribe(topic).await, + Coordinator::Nats(store) => store.subscribe(topic).await, #[cfg(feature = "zenoh")] - PubSubStore::Zenoh(store) => store.subscribe(topic).await, + Coordinator::Zenoh(store) => store.subscribe(topic).await, #[cfg(feature = "kafka")] - PubSubStore::Kafka(store) => store.subscribe(topic).await, - PubSubStore::None => Err(trc::StoreEvent::NotSupported.into_err()), + Coordinator::Kafka(store) => store.subscribe(topic).await, + Coordinator::None => Err(trc::StoreEvent::NotSupported.into_err()), } } pub fn is_none(&self) -> bool { - matches!(self, PubSubStore::None) + matches!(self, Coordinator::None) } } diff --git a/crates/coordinator/src/lib.rs b/crates/coordinator/src/lib.rs new file mode 100644 index 00000000..73f530fc --- /dev/null +++ b/crates/coordinator/src/lib.rs @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use std::sync::Arc; + +pub mod backend; +pub mod dispatch; + +#[derive(Clone, Default)] +pub enum Coordinator { + #[cfg(feature = "redis")] + Redis(Arc), + #[cfg(feature = "nats")] + Nats(Arc), + #[cfg(feature = "zenoh")] + Zenoh(Arc), + #[cfg(feature = "kafka")] + Kafka(Arc), + #[default] + None, +} + +pub enum PubSubStream { + #[cfg(feature = "redis")] + Redis(crate::backend::redis::RedisPubSubStream), + #[cfg(feature = "redis")] + RedisCluster(crate::backend::redis::RedisClusterPubSubStream), + #[cfg(feature = "nats")] + Nats(crate::backend::nats::pubsub::NatsPubSubStream), + #[cfg(feature = "zenoh")] + Zenoh(crate::backend::zenoh::pubsub::ZenohPubSubStream), + #[cfg(feature = "kafka")] + Kafka(crate::backend::kafka::pubsub::KafkaPubSubStream), + #[cfg(not(any(feature = "redis", feature = "nats")))] + Unimplemented, +} + +pub enum Msg { + #[cfg(feature = "redis")] + Redis(redis::Msg), + #[cfg(feature = "nats")] + Nats(async_nats::Message), + #[cfg(feature = "zenoh")] + Zenoh(Vec), + #[cfg(feature = "kafka")] + Kafka(Vec), + #[cfg(not(any(feature = "redis", feature = "nats")))] + Unimplemented, +} diff --git a/crates/main/Cargo.toml b/crates/main/Cargo.toml index da8c9af5..c0b7c7c3 100644 --- a/crates/main/Cargo.toml +++ b/crates/main/Cargo.toml @@ -16,6 +16,7 @@ path = "src/main.rs" [dependencies] store = { path = "../store" } +coordinator = { path = "../coordinator" } jmap = { path = "../jmap" } types = { path = "../types" } smtp = { path = "../smtp" } @@ -47,11 +48,11 @@ postgres = ["store/postgres"] mysql = ["store/mysql"] rocks = ["store/rocks"] s3 = ["store/s3"] -redis = ["store/redis"] -nats = ["store/nats"] +redis = ["store/redis", "coordinator/redis"] azure = ["store/azure"] -zenoh = ["store/zenoh"] -kafka = ["store/kafka"] +nats = ["coordinator/nats"] +zenoh = ["coordinator/zenoh"] +kafka = ["coordinator/kafka"] enterprise = [ "jmap/enterprise", "smtp/enterprise", "common/enterprise", diff --git a/crates/registry/Cargo.toml b/crates/registry/Cargo.toml new file mode 100644 index 00000000..fa515bf2 --- /dev/null +++ b/crates/registry/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "registry" +version = "0.15.4" +edition = "2024" + +[dependencies] +utils = { path = "../utils" } +trc = { path = "../trc" } +types = { path = "../types" } +serde = { version = "1.0", features = ["derive"]} +serde_json = "1.0" +hashify = "0.2.7" + +[features] +test_mode = [] +enterprise = [] diff --git a/crates/registry/src/lib.rs b/crates/registry/src/lib.rs new file mode 100644 index 00000000..2156a015 --- /dev/null +++ b/crates/registry/src/lib.rs @@ -0,0 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +pub mod pickle; +pub mod schema; +pub mod types; diff --git a/crates/registry/src/pickle.rs b/crates/registry/src/pickle.rs new file mode 100644 index 00000000..8cdbf9c3 --- /dev/null +++ b/crates/registry/src/pickle.rs @@ -0,0 +1,204 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use crate::types::EnumType; +use std::collections::HashMap; + +pub trait Pickle: Sized { + fn pickle(&self, out: &mut Vec); + fn unpickle(stream: &mut PickledStream<'_>) -> Option; +} + +pub struct PickledStream<'x> { + data: &'x [u8], + pos: usize, +} + +impl<'x> PickledStream<'x> { + pub fn new(data: &'x [u8]) -> Self { + PickledStream { data, pos: 0 } + } + + pub fn read(&mut self) -> Option { + let byte = *self.data.get(self.pos)?; + self.pos += 1; + Some(byte) + } + + pub fn read_bytes(&mut self, len: usize) -> Option<&'x [u8]> { + let bytes = self.data.get(self.pos..self.pos + len)?; + self.pos += len; + Some(bytes) + } + + pub fn eof(&self) -> bool { + self.pos >= self.data.len() + } +} + +impl Pickle for u16 { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.to_le_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 2]; + arr.copy_from_slice(stream.read_bytes(2)?); + Some(u16::from_le_bytes(arr)) + } +} + +impl Pickle for u64 { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.to_le_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(stream.read_bytes(8)?); + Some(u64::from_le_bytes(arr)) + } +} + +impl Pickle for i64 { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.to_le_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(stream.read_bytes(8)?); + Some(i64::from_le_bytes(arr)) + } +} + +impl Pickle for f64 { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.to_le_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(stream.read_bytes(8)?); + Some(f64::from_le_bytes(arr)) + } +} + +impl Pickle for bool { + fn pickle(&self, out: &mut Vec) { + out.push(if *self { 1 } else { 0 }); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + match stream.read()? { + 0 => Some(false), + 1 => Some(true), + _ => None, + } + } +} + +impl Pickle for String { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&(self.len() as u32).to_le_bytes()); + out.extend_from_slice(self.as_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut len_arr = [0u8; 4]; + len_arr.copy_from_slice(stream.read_bytes(4)?); + let bytes = stream.read_bytes(u32::from_le_bytes(len_arr) as usize)?; + String::from_utf8(bytes.to_vec()).ok() + } +} + +impl Pickle for T { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.to_id().to_le_bytes()); + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut id_arr = [0u8; 2]; + id_arr.copy_from_slice(stream.read_bytes(2)?); + Self::from_id(u16::from_le_bytes(id_arr)) + } +} + +impl Pickle for Option +where + T: Pickle, +{ + fn pickle(&self, out: &mut Vec) { + match self { + Some(value) => { + out.push(1); + value.pickle(out); + } + None => { + out.push(0); + } + } + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + match stream.read()? { + 0 => Some(None), + 1 => T::unpickle(stream).map(Some), + _ => None, + } + } +} + +impl Pickle for Vec +where + T: Pickle, +{ + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&(self.len() as u32).to_le_bytes()); + for item in self { + item.pickle(out); + } + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut len_arr = [0u8; 4]; + len_arr.copy_from_slice(stream.read_bytes(4)?); + let len = u32::from_le_bytes(len_arr) as usize; + let mut vec = Vec::with_capacity(len); + for _ in 0..len { + vec.push(T::unpickle(stream)?); + } + Some(vec) + } +} + +impl Pickle for HashMap +where + K: Pickle + std::hash::Hash + Eq, + V: Pickle, + S: std::hash::BuildHasher + Default, +{ + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&(self.len() as u32).to_le_bytes()); + for (key, value) in self { + key.pickle(out); + value.pickle(out); + } + } + + fn unpickle(stream: &mut PickledStream<'_>) -> Option { + let mut len_arr = [0u8; 4]; + len_arr.copy_from_slice(stream.read_bytes(4)?); + let len = u32::from_le_bytes(len_arr) as usize; + let mut map = HashMap::with_capacity_and_hasher(len, S::default()); + for _ in 0..len { + let key = K::unpickle(stream)?; + let value = V::unpickle(stream)?; + map.insert(key, value); + } + Some(map) + } +} diff --git a/crates/registry/src/schema/mod.rs b/crates/registry/src/schema/mod.rs new file mode 100644 index 00000000..e1746054 --- /dev/null +++ b/crates/registry/src/schema/mod.rs @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +#[allow(clippy::derivable_impls)] +pub mod enums; +pub mod enums_impl; +pub mod prelude; +pub mod properties; +pub mod properties_impl; +#[allow(clippy::large_enum_variant)] +pub mod structs; +#[allow(clippy::derivable_impls)] +pub mod structs_impl; diff --git a/crates/registry/src/schema/prelude.rs b/crates/registry/src/schema/prelude.rs new file mode 100644 index 00000000..50832109 --- /dev/null +++ b/crates/registry/src/schema/prelude.rs @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +pub use crate::pickle::Pickle; +pub use crate::schema::enums::*; +pub use crate::schema::properties::*; +pub use crate::schema::structs::*; +pub use crate::types::EnumType; +pub use crate::types::datetime::UTCDateTime; +pub use crate::types::duration::Duration; +pub use crate::types::error::*; +pub use crate::types::id::Id; +pub use crate::types::ipaddr::IpAddr; +pub use crate::types::ipmask::IpAddrOrMask; +pub use crate::types::socketaddr::SocketAddr; +pub use serde::{Deserialize, Serialize}; +pub use std::collections::HashMap; +pub use std::str::FromStr; diff --git a/crates/registry/src/types/datetime.rs b/crates/registry/src/types/datetime.rs new file mode 100644 index 00000000..38ce92fc --- /dev/null +++ b/crates/registry/src/types/datetime.rs @@ -0,0 +1,284 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use crate::pickle::{Pickle, PickledStream}; +use std::{fmt::Display, str::FromStr}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(transparent)] +pub struct UTCDateTime(i64); + +struct DateTime { + pub year: u16, + pub month: u8, + pub day: u8, + pub hour: u8, + pub minute: u8, + pub second: u8, + pub tz_before_gmt: bool, + pub tz_hour: u8, + pub tz_minute: u8, +} + +impl FromStr for UTCDateTime { + type Err = (); + + fn from_str(s: &str) -> Result { + // 2004 - 06 - 28 T 23 : 43 : 45 . 000 Z + // 1969 - 02 - 13 T 23 : 32 : 00 - 03 : 30 + // 0 1 2 3 4 5 6 7 + + let mut pos = 0; + let mut parts = [0u32; 8]; + let mut parts_sizes = [ + 4u32, // Year (0) + 2u32, // Month (1) + 2u32, // Day (2) + 2u32, // Hour (3) + 2u32, // Minute (4) + 2u32, // Second (5) + 2u32, // TZ Hour (6) + 2u32, // TZ Minute (7) + ]; + let mut skip_digits = false; + let mut is_plus = true; + + for ch in s.as_bytes() { + match ch { + b'0'..=b'9' => { + if !skip_digits { + if parts_sizes[pos] > 0 { + parts_sizes[pos] -= 1; + parts[pos] += (ch - b'0') as u32 * u32::pow(10, parts_sizes[pos]); + } else { + break; + } + } + } + b'-' => { + if pos <= 1 { + pos += 1; + } else if pos == 5 { + pos += 1; + is_plus = false; + skip_digits = false; + } else { + break; + } + } + b'T' => { + if pos == 2 { + pos += 1; + } else { + break; + } + } + b':' => { + if [3, 4, 6].contains(&pos) { + pos += 1; + } else { + break; + } + } + b'+' => { + if pos == 5 { + pos += 1; + skip_digits = false; + } else { + break; + } + } + b'.' => { + if pos == 5 { + skip_digits = true; + } else { + break; + } + } + b'Z' | b'z' => (), + _ => { + break; + } + } + } + + let dt = DateTime { + year: parts[0] as u16, + month: parts[1] as u8, + day: parts[2] as u8, + hour: parts[3] as u8, + minute: parts[4] as u8, + second: parts[5] as u8, + tz_hour: parts[6] as u8, + tz_minute: parts[7] as u8, + tz_before_gmt: !is_plus, + }; + + if pos >= 5 && dt.is_valid() { + Ok(UTCDateTime(dt.timestamp())) + } else { + Err(()) + } + } +} + +impl UTCDateTime { + pub fn from_timestamp(timestamp: i64) -> Self { + UTCDateTime(timestamp) + } + + pub fn timestamp(&self) -> i64 { + self.0 + } + + pub fn is_valid(&self) -> bool { + self.0 != i64::MAX + } +} + +impl DateTime { + pub fn from_timestamp(timestamp: i64) -> Self { + // Ported from http://howardhinnant.github.io/date_algorithms.html#civil_from_days + let (z, seconds) = ((timestamp / 86400) + 719468, timestamp % 86400); + let era: i64 = (if z >= 0 { z } else { z - 146096 }) / 146097; + let doe: u64 = (z - era * 146097) as u64; // [0, 146096] + let yoe: u64 = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399] + let y: i64 = (yoe as i64) + era * 400; + let doy: u64 = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365] + let mp = (5 * doy + 2) / 153; // [0, 11] + let d: u64 = doy - (153 * mp + 2) / 5 + 1; // [1, 31] + let m: u64 = if mp < 10 { mp + 3 } else { mp - 9 }; // [1, 12] + let (h, mn, s) = (seconds / 3600, (seconds / 60) % 60, seconds % 60); + + DateTime { + year: (y + i64::from(m <= 2)) as u16, + month: m as u8, + day: d as u8, + hour: h as u8, + minute: mn as u8, + second: s as u8, + tz_before_gmt: false, + tz_hour: 0, + tz_minute: 0, + } + } + + #[inline(always)] + pub fn is_valid(&self) -> bool { + (0..=23).contains(&self.tz_hour) + && (1970..=3000).contains(&self.year) + && (0..=59).contains(&self.tz_minute) + && (1..=12).contains(&self.month) + && (1..=31).contains(&self.day) + && (0..=23).contains(&self.hour) + && (0..=59).contains(&self.minute) + && (0..=59).contains(&self.second) + } + + pub fn timestamp(&self) -> i64 { + // Ported from https://github.com/protocolbuffers/upb/blob/22182e6e/upb/json_decode.c#L982-L992 + let month = self.month as u32; + let year_base = 4800; /* Before min year, multiple of 400. */ + let m_adj = month.wrapping_sub(3); /* March-based month. */ + let carry = i64::from(m_adj > month); + let adjust = if carry > 0 { 12 } else { 0 }; + let y_adj = self.year as i64 + year_base - carry; + let month_days = ((m_adj.wrapping_add(adjust)) * 62719 + 769) / 2048; + let leap_days = y_adj / 4 - y_adj / 100 + y_adj / 400; + (y_adj * 365 + leap_days + month_days as i64 + (self.day as i64 - 1) - 2472632) * 86400 + + self.hour as i64 * 3600 + + self.minute as i64 * 60 + + self.second as i64 + + ((self.tz_hour as i64 * 3600 + self.tz_minute as i64 * 60) + * if self.tz_before_gmt { 1 } else { -1 }) + } +} + +impl Display for UTCDateTime { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let dt = DateTime::from_timestamp(self.0); + + write!( + f, + "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z", + dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, + ) + } +} + +impl Default for UTCDateTime { + fn default() -> Self { + UTCDateTime(i64::MAX) + } +} + +impl serde::Serialize for UTCDateTime { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for UTCDateTime { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + UTCDateTime::from_str(<&str>::deserialize(deserializer)?) + .map_err(|_| serde::de::Error::custom("invalid DateTime")) + } +} + +impl Pickle for UTCDateTime { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.0.to_le_bytes()); + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(data.read_bytes(8)?); + Some(UTCDateTime(i64::from_le_bytes(arr))) + } +} + +impl From for UTCDateTime { + fn from(value: u64) -> Self { + UTCDateTime(value as i64) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use crate::types::datetime::UTCDateTime; + + #[test] + fn parse_jmap_date() { + for (input, _) in [ + ("1997-11-21T09:55:06-06:00", "1997-11-21T09:55:06-06:00"), + ("1997-11-21T09:55:06+00:00", "1997-11-21T09:55:06Z"), + ("2021-01-01T09:55:06+02:00", "2021-01-01T09:55:06+02:00"), + ("2004-06-28T23:43:45.000Z", "2004-06-28T23:43:45Z"), + ("1997-11-21T09:55:06.123+00:00", "1997-11-21T09:55:06Z"), + ( + "2021-01-01T09:55:06.4567+02:00", + "2021-01-01T09:55:06+02:00", + ), + ] { + let date = UTCDateTime::from_str(input).unwrap(); + //assert_eq!(date.to_string(), expected_result); + + let timestamp = date.timestamp(); + assert_eq!( + UTCDateTime::from_timestamp(timestamp).timestamp(), + timestamp + ); + } + } +} diff --git a/crates/registry/src/types/duration.rs b/crates/registry/src/types/duration.rs new file mode 100644 index 00000000..973e4fa6 --- /dev/null +++ b/crates/registry/src/types/duration.rs @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use std::{fmt::Display, str::FromStr}; +use crate::pickle::{Pickle, PickledStream}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Duration(pub std::time::Duration); + +impl Duration { + pub fn from_millis(millis: u64) -> Self { + Duration(std::time::Duration::from_millis(millis)) + } + + pub fn into_inner(self) -> std::time::Duration { + self.0 + } + + pub fn is_valid(&self) -> bool { + self.0.as_millis() > 0 + } +} + +impl Default for Duration { + fn default() -> Self { + Duration(std::time::Duration::from_millis(0)) + } +} + +impl Display for Duration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.as_millis()) + } +} + +impl serde::Serialize for Duration { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for Duration { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + ::deserialize(deserializer) + .map(std::time::Duration::from_millis) + .map(Duration) + .map_err(|_| serde::de::Error::custom("invalid Duration")) + } +} + +impl AsRef for Duration { + fn as_ref(&self) -> &std::time::Duration { + &self.0 + } +} + +impl PartialOrd for Duration { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Duration { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +impl FromStr for Duration { + type Err = String; + + fn from_str(value: &str) -> Result { + let mut digits = String::new(); + let mut multiplier = String::new(); + + for ch in value.chars() { + if ch.is_ascii_digit() { + digits.push(ch); + } else if !ch.is_ascii_whitespace() { + multiplier.push(ch.to_ascii_lowercase()); + } + } + + let multiplier = match multiplier.as_str() { + "d" => 24 * 60 * 60 * 1000, + "h" => 60 * 60 * 1000, + "m" => 60 * 1000, + "s" => 1000, + "ms" | "" => 1, + _ => return Err(format!("Invalid duration value {:?}.", value)), + }; + + digits + .parse::() + .ok() + .map(|num| std::time::Duration::from_millis(num * multiplier)) + .map(Duration) + .ok_or_else(|| format!("Invalid duration value {:?}.", value)) + } +} + +impl Pickle for Duration { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&(self.0.as_millis() as u64).to_le_bytes()); + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(data.read_bytes(8)?); + Some(Duration(std::time::Duration::from_millis( + u64::from_le_bytes(arr), + ))) + } +} diff --git a/crates/registry/src/types/error.rs b/crates/registry/src/types/error.rs new file mode 100644 index 00000000..9355ed1c --- /dev/null +++ b/crates/registry/src/types/error.rs @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use crate::schema::prelude::Property; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ValidationErrorType { + Invalid, + Required, + MinItems(usize), + MaxItems(usize), + MaxLength(usize), + MinLength(usize), + MaxValue(i64), + MinValue(i64), +} + +pub struct ValidationError { + pub property: Property, + pub typ: ValidationErrorType, +} + +impl ValidationError { + pub fn new(property: Property, typ: ValidationErrorType) -> Self { + Self { property, typ } + } + + pub fn required(property: Property) -> Self { + Self { + property, + typ: ValidationErrorType::Required, + } + } + + pub fn invalid(property: Property) -> Self { + Self { + property, + typ: ValidationErrorType::Invalid, + } + } + + pub fn min_items(property: Property, value: usize) -> Self { + Self { + property, + typ: ValidationErrorType::MinItems(value), + } + } + + pub fn max_items(property: Property, value: usize) -> Self { + Self { + property, + typ: ValidationErrorType::MaxItems(value), + } + } + + pub fn max_length(property: Property, value: usize) -> Self { + Self { + property, + typ: ValidationErrorType::MaxLength(value), + } + } + + pub fn min_length(property: Property, value: usize) -> Self { + Self { + property, + typ: ValidationErrorType::MinLength(value), + } + } + + pub fn max_value(property: Property, value: i64) -> Self { + Self { + property, + typ: ValidationErrorType::MaxValue(value), + } + } + + pub fn min_value(property: Property, value: i64) -> Self { + Self { + property, + typ: ValidationErrorType::MinValue(value), + } + } +} diff --git a/crates/registry/src/types/id.rs b/crates/registry/src/types/id.rs new file mode 100644 index 00000000..860c0e66 --- /dev/null +++ b/crates/registry/src/types/id.rs @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use crate::{ + pickle::{Pickle, PickledStream}, + schema::prelude::Object, +}; +use std::str::FromStr; +use utils::codec::base32_custom::{BASE32_ALPHABET, BASE32_INVERSE}; + +#[derive(Debug, PartialEq, Clone, Copy, Eq, Hash)] +#[repr(transparent)] +pub struct Id(u64); + +impl Id { + pub fn new(object: Object, id: u64) -> Self { + Id(id & (u64::MAX >> 16) | ((object as u64) << 48)) + } + + pub fn id(&self) -> u64 { + self.0 + } + + pub fn is_valid(&self) -> bool { + self.0 != u64::MAX + } + + // From https://github.com/archer884/crockford by J/A + // License: MIT/Apache 2.0 + pub fn as_string(&self) -> String { + match self.0 { + 0 => "a".to_string(), + mut n => { + // Used for the initial shift. + const QUAD_SHIFT: usize = 60; + const QUAD_RESET: usize = 4; + + // Used for all subsequent shifts. + const FIVE_SHIFT: usize = 59; + const FIVE_RESET: usize = 5; + + // After we clear the four most significant bits, the four least significant bits will be + // replaced with 0001. We can then know to stop once the four most significant bits are, + // likewise, 0001. + const STOP_BIT: u64 = 1 << QUAD_SHIFT; + + let mut buf = String::with_capacity(7); + + // Start by getting the most significant four bits. We get four here because these would be + // leftovers when starting from the least significant bits. In either case, tag the four least + // significant bits with our stop bit. + match (n >> QUAD_SHIFT) as usize { + // Eat leading zero-bits. This should not be done if the first four bits were non-zero. + // Additionally, we *must* do this in increments of five bits. + 0 => { + n <<= QUAD_RESET; + n |= 1; + n <<= n.leading_zeros() / 5 * 5; + } + + // Write value of first four bytes. + i => { + n <<= QUAD_RESET; + n |= 1; + buf.push(char::from(BASE32_ALPHABET[i])); + } + } + + // From now until we reach the stop bit, take the five most significant bits and then shift + // left by five bits. + while n != STOP_BIT { + buf.push(char::from(BASE32_ALPHABET[(n >> FIVE_SHIFT) as usize])); + n <<= FIVE_RESET; + } + + buf + } + } + } +} + +impl Object { + pub fn id(&self, id: u64) -> Id { + Id::new(*self, id) + } + + pub fn singleton(&self) -> Id { + Id::new(*self, u64::MAX) + } +} + +impl FromStr for Id { + type Err = (); + + fn from_str(s: &str) -> Result { + let mut id = 0; + + for &ch in s.as_bytes() { + let i = BASE32_INVERSE[ch as usize]; + if i != u8::MAX { + id = (id << 5) | i as u64; + } else { + return Err(()); + } + } + + Ok(Id(id)) + } +} + +impl Default for Id { + fn default() -> Self { + Id(u64::MAX) + } +} + +impl serde::Serialize for Id { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.as_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for Id { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Id::from_str(<&str>::deserialize(deserializer)?) + .map_err(|_| serde::de::Error::custom("invalid Registry ID")) + } +} + +impl std::fmt::Display for Id { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.as_string()) + } +} + +impl Pickle for Id { + fn pickle(&self, out: &mut Vec) { + out.extend_from_slice(&self.0.to_le_bytes()); + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + let mut arr = [0u8; 8]; + arr.copy_from_slice(data.read_bytes(8)?); + Some(Id(u64::from_le_bytes(arr))) + } +} diff --git a/crates/registry/src/types/ipaddr.rs b/crates/registry/src/types/ipaddr.rs new file mode 100644 index 00000000..9216b9ca --- /dev/null +++ b/crates/registry/src/types/ipaddr.rs @@ -0,0 +1,114 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use std::{fmt::Display, net::Ipv4Addr, str::FromStr}; + +use crate::pickle::{Pickle, PickledStream}; + +#[derive(Debug, Clone, PartialEq)] +pub struct IpAddr(pub std::net::IpAddr); + +impl IpAddr { + pub fn into_inner(self) -> std::net::IpAddr { + self.0 + } + + pub fn is_valid(&self) -> bool { + !matches!( + self.0, + std::net::IpAddr::V4(addr) if addr == Ipv4Addr::UNSPECIFIED + ) + } +} + +impl FromStr for IpAddr { + type Err = String; + + fn from_str(s: &str) -> Result { + s.parse::() + .map(IpAddr) + .map_err(|err| err.to_string()) + } +} + +impl Display for IpAddr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl serde::Serialize for IpAddr { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for IpAddr { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + IpAddr::from_str(<&str>::deserialize(deserializer)?) + .map_err(|_| serde::de::Error::custom("invalid IpAddr")) + } +} + +impl AsRef for IpAddr { + fn as_ref(&self) -> &std::net::IpAddr { + &self.0 + } +} + +impl Default for IpAddr { + fn default() -> Self { + IpAddr(std::net::IpAddr::V4(Ipv4Addr::UNSPECIFIED)) + } +} + +impl Pickle for std::net::IpAddr { + fn pickle(&self, out: &mut Vec) { + match self { + std::net::IpAddr::V4(addr) => { + out.push(4); + out.extend_from_slice(&addr.octets()); + } + std::net::IpAddr::V6(addr) => { + out.push(6); + out.extend_from_slice(&addr.octets()); + } + } + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + let kind = data.read()?; + match kind { + 4 => { + let mut arr = [0u8; 4]; + arr.copy_from_slice(data.read_bytes(4)?); + Some(std::net::IpAddr::V4(Ipv4Addr::from(arr))) + } + 6 => { + let mut arr = [0u8; 16]; + arr.copy_from_slice(data.read_bytes(16)?); + Some(std::net::IpAddr::V6(std::net::Ipv6Addr::from(arr))) + } + _ => None, + } + } +} + +impl Pickle for IpAddr { + fn pickle(&self, out: &mut Vec) { + self.0.pickle(out); + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + std::net::IpAddr::unpickle(data).map(IpAddr) + } +} diff --git a/crates/registry/src/types/ipmask.rs b/crates/registry/src/types/ipmask.rs new file mode 100644 index 00000000..c67c5a98 --- /dev/null +++ b/crates/registry/src/types/ipmask.rs @@ -0,0 +1,244 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use std::{ + fmt::{Display, Formatter}, + net::{IpAddr, Ipv4Addr, Ipv6Addr}, + str::FromStr, +}; + +use crate::pickle::{Pickle, PickledStream}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum IpAddrOrMask { + V4 { addr: Ipv4Addr, mask: u32 }, + V6 { addr: Ipv6Addr, mask: u128 }, +} + +impl IpAddrOrMask { + pub fn is_valid(&self) -> bool { + !matches!( + self, + IpAddrOrMask::V4 { addr, mask: _ } if addr == &Ipv4Addr::UNSPECIFIED + ) + } + + pub fn matches(&self, remote: &IpAddr) -> bool { + match self { + IpAddrOrMask::V4 { addr, mask } => match *mask { + u32::MAX => match remote { + IpAddr::V4(remote) => addr == remote, + IpAddr::V6(remote) => { + if let Some(remote) = remote.to_ipv4_mapped() { + addr == &remote + } else { + false + } + } + }, + 0 => { + matches!(remote, IpAddr::V4(_)) + } + _ => { + u32::from_be_bytes(match remote { + IpAddr::V4(ip) => ip.octets(), + IpAddr::V6(ip) => { + if let Some(ip) = ip.to_ipv4() { + ip.octets() + } else { + return false; + } + } + }) & mask + == u32::from_be_bytes(addr.octets()) & mask + } + }, + IpAddrOrMask::V6 { addr, mask } => match *mask { + u128::MAX => match remote { + IpAddr::V6(remote) => remote == addr, + IpAddr::V4(remote) => &remote.to_ipv6_mapped() == addr, + }, + 0 => { + matches!(remote, IpAddr::V6(_)) + } + _ => { + u128::from_be_bytes(match remote { + IpAddr::V6(ip) => ip.octets(), + IpAddr::V4(ip) => ip.to_ipv6_mapped().octets(), + }) & mask + == u128::from_be_bytes(addr.octets()) & mask + } + }, + } + } +} + +impl FromStr for IpAddrOrMask { + type Err = String; + + fn from_str(value: &str) -> Result { + if let Some((addr, mask)) = value.rsplit_once('/') { + if let (Ok(addr), Ok(mask)) = + (addr.trim().parse::(), mask.trim().parse::()) + { + match addr { + IpAddr::V4(addr) if (8..=32).contains(&mask) => { + return Ok(IpAddrOrMask::V4 { + addr, + mask: u32::MAX << (32 - mask), + }); + } + IpAddr::V6(addr) if (8..=128).contains(&mask) => { + return Ok(IpAddrOrMask::V6 { + addr, + mask: u128::MAX << (128 - mask), + }); + } + _ => (), + } + } + } else { + match value.trim().parse::() { + Ok(IpAddr::V4(addr)) => { + return Ok(IpAddrOrMask::V4 { + addr, + mask: u32::MAX, + }); + } + Ok(IpAddr::V6(addr)) => { + return Ok(IpAddrOrMask::V6 { + addr, + mask: u128::MAX, + }); + } + _ => (), + } + } + + Err(format!("Invalid IP address {:?}", value,)) + } +} + +impl Display for IpAddrOrMask { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + IpAddrOrMask::V4 { addr, mask } => { + if (*mask) == u32::MAX { + write!(f, "{}", addr) + } else { + let prefix = mask.count_ones(); + write!(f, "{}/{}", addr, prefix) + } + } + IpAddrOrMask::V6 { addr, mask } => { + if (*mask) == u128::MAX { + write!(f, "{}", addr) + } else { + let prefix = mask.count_ones(); + write!(f, "{}/{}", addr, prefix) + } + } + } + } +} + +impl serde::Serialize for IpAddrOrMask { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for IpAddrOrMask { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + IpAddrOrMask::from_str(<&str>::deserialize(deserializer)?) + .map_err(|_| serde::de::Error::custom("invalid IpAddrOrMask")) + } +} + +impl Default for IpAddrOrMask { + fn default() -> Self { + IpAddrOrMask::V4 { + addr: Ipv4Addr::UNSPECIFIED, + mask: u32::MAX, + } + } +} + +impl Pickle for IpAddrOrMask { + fn pickle(&self, out: &mut Vec) { + match self { + IpAddrOrMask::V4 { addr, mask } => { + out.push(4); + out.extend_from_slice(&addr.octets()); + out.extend_from_slice(&mask.to_le_bytes()); + } + IpAddrOrMask::V6 { addr, mask } => { + out.push(6); + out.extend_from_slice(&addr.octets()); + out.extend_from_slice(&mask.to_le_bytes()); + } + } + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + match data.read()? { + 4 => { + let mut addr_arr = [0u8; 4]; + addr_arr.copy_from_slice(data.read_bytes(4)?); + let mut mask_arr = [0u8; 4]; + mask_arr.copy_from_slice(data.read_bytes(4)?); + Some(IpAddrOrMask::V4 { + addr: Ipv4Addr::from(addr_arr), + mask: u32::from_le_bytes(mask_arr), + }) + } + 6 => { + let mut addr_arr = [0u8; 16]; + addr_arr.copy_from_slice(data.read_bytes(16)?); + let mut mask_arr = [0u8; 16]; + mask_arr.copy_from_slice(data.read_bytes(16)?); + Some(IpAddrOrMask::V6 { + addr: Ipv6Addr::from(addr_arr), + mask: u128::from_le_bytes(mask_arr), + }) + } + _ => None, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_ipaddrmask() { + for (mask, ip) in [ + ("10.0.0.0/8", "10.30.20.11"), + ("10.0.0.0/8", "10.0.13.73"), + ("192.168.1.1", "192.168.1.1"), + ] { + let mask = IpAddrOrMask::from_str(mask).unwrap(); + let ip = ip.parse::().unwrap(); + assert!(mask.matches(&ip)); + } + + for (mask, ip) in [ + ("10.0.0.0/8", "11.30.20.11"), + ("192.168.1.1", "193.168.1.1"), + ] { + let mask = IpAddrOrMask::from_str(mask).unwrap(); + let ip = ip.parse::().unwrap(); + assert!(!mask.matches(&ip)); + } + } +} diff --git a/crates/registry/src/types/mod.rs b/crates/registry/src/types/mod.rs new file mode 100644 index 00000000..98567f79 --- /dev/null +++ b/crates/registry/src/types/mod.rs @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +pub mod datetime; +pub mod duration; +pub mod error; +pub mod id; +pub mod ipaddr; +pub mod ipmask; +pub mod socketaddr; + +pub trait EnumType: Sized { + fn parse(s: &str) -> Option; + fn as_str(&self) -> &'static str; + fn from_id(id: u16) -> Option; + fn to_id(&self) -> u16; +} diff --git a/crates/registry/src/types/socketaddr.rs b/crates/registry/src/types/socketaddr.rs new file mode 100644 index 00000000..c4dab835 --- /dev/null +++ b/crates/registry/src/types/socketaddr.rs @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use std::{fmt::Display, str::FromStr}; + +use crate::pickle::{Pickle, PickledStream}; + +#[derive(Debug, Clone, PartialEq)] +pub struct SocketAddr(pub std::net::SocketAddr); + +impl SocketAddr { + pub fn into_inner(self) -> std::net::SocketAddr { + self.0 + } + + pub fn is_valid(&self) -> bool { + !self.0.ip().is_unspecified() + } +} + +impl FromStr for SocketAddr { + type Err = String; + + fn from_str(s: &str) -> Result { + s.parse::() + .map(SocketAddr) + .map_err(|err| err.to_string()) + } +} + +impl Display for SocketAddr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} + +impl serde::Serialize for SocketAddr { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str(self.to_string().as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for SocketAddr { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + SocketAddr::from_str(<&str>::deserialize(deserializer)?) + .map_err(|_| serde::de::Error::custom("invalid SocketAddr")) + } +} + +impl Default for SocketAddr { + fn default() -> Self { + SocketAddr(std::net::SocketAddr::from(([0, 0, 0, 0], 0))) + } +} + +impl AsRef for SocketAddr { + fn as_ref(&self) -> &std::net::SocketAddr { + &self.0 + } +} + +impl Pickle for SocketAddr { + fn pickle(&self, out: &mut Vec) { + self.0.ip().pickle(out); + out.extend_from_slice(&self.0.port().to_le_bytes()); + } + + fn unpickle(data: &mut PickledStream<'_>) -> Option { + let ip = std::net::IpAddr::unpickle(data)?; + let mut port_bytes = [0u8; 2]; + port_bytes.copy_from_slice(data.read_bytes(2)?); + let port = u16::from_le_bytes(port_bytes); + Some(SocketAddr(std::net::SocketAddr::new(ip, port))) + } +} diff --git a/crates/store/Cargo.toml b/crates/store/Cargo.toml index 1115f553..2de076fe 100644 --- a/crates/store/Cargo.toml +++ b/crates/store/Cargo.toml @@ -8,12 +8,12 @@ utils = { path = "../utils" } types = { path = "../types" } nlp = { path = "../nlp" } trc = { path = "../trc" } +registry = { path = "../registry" } rocksdb = { version = "0.24", optional = true, features = ["multi-threaded-cf"] } foundationdb = { version = "0.9.2", features = ["embedded-fdb-include", "fdb-7_3"], optional = true } rusqlite = { version = "0.37", features = ["bundled"], optional = true } #rust-s3 = { version = "0.37", default-features = false, features = ["tokio-rustls-tls"], optional = true } rust-s3 = { version = "0.35", default-features = false, features = ["tokio-rustls-tls", "no-verify-ssl"], optional = true } -async-nats = { version = "0.44", default-features = false, features = ["server_2_10", "server_2_11", "ring"], optional = true } azure_core = { version = "0.21.0", optional = true } azure_storage = { version = "0.21.0", default-features = false, features = ["enable_reqwest_rustls", "hmac_rust"], optional = true } azure_storage_blobs = { version = "0.21.0", default-features = false, features = ["enable_reqwest_rustls", "hmac_rust"], optional = true } @@ -51,8 +51,6 @@ bitpacking = "0.9.2" memchr = { version = "2.7" } rkyv = { version = "0.8.10", features = ["little_endian"] } compact_str = "0.9.0" -zenoh = { version = "1.3.4", default-features = false, features = ["auth_pubkey", "transport_multilink", "transport_compression", "transport_quic", "transport_tcp", "transport_tls", "transport_udp"], optional = true } -rdkafka = { version = "0.38", features = ["cmake-build"], optional = true } rustls_021 = { package = "rustls", version = "0.21", default-features = false, features = ["dangerous_configuration"], optional = true } [dev-dependencies] @@ -74,10 +72,5 @@ azure = ["azure_core", "azure_storage", "azure_storage_blobs"] # In-memory stores redis = ["dep:redis", "deadpool", "futures"] -# Pubsub -nats = ["async-nats"] -zenoh = ["dep:zenoh"] -kafka = ["rdkafka"] - enterprise = [] test_mode = [] diff --git a/crates/store/src/backend/mod.rs b/crates/store/src/backend/mod.rs index d17e424b..7f691f81 100644 --- a/crates/store/src/backend/mod.rs +++ b/crates/store/src/backend/mod.rs @@ -11,14 +11,10 @@ pub mod elastic; pub mod foundationdb; pub mod fs; pub mod http; -#[cfg(feature = "kafka")] -pub mod kafka; pub mod meili; pub mod memory; #[cfg(feature = "mysql")] pub mod mysql; -#[cfg(feature = "nats")] -pub mod nats; #[cfg(feature = "postgres")] pub mod postgres; #[cfg(feature = "redis")] @@ -29,8 +25,6 @@ pub mod rocksdb; pub mod s3; #[cfg(feature = "sqlite")] pub mod sqlite; -#[cfg(feature = "zenoh")] -pub mod zenoh; // SPDX-SnippetBegin // SPDX-FileCopyrightText: 2020 Stalwart Labs LLC diff --git a/crates/store/src/backend/redis/mod.rs b/crates/store/src/backend/redis/mod.rs index 6d005aaf..29d451bc 100644 --- a/crates/store/src/backend/redis/mod.rs +++ b/crates/store/src/backend/redis/mod.rs @@ -4,8 +4,6 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use std::{fmt::Display, time::Duration}; - use deadpool::{ Runtime, managed::{Manager, Pool}, @@ -14,28 +12,28 @@ use redis::{ Client, ProtocolVersion, cluster::{ClusterClient, ClusterClientBuilder}, }; +use std::{fmt::Display, time::Duration}; use utils::config::{Config, utils::AsKey}; pub mod lookup; pub mod pool; -pub mod pubsub; #[derive(Debug)] pub struct RedisStore { - pool: RedisPool, + pub pool: RedisPool, } -struct RedisConnectionManager { - client: Client, +pub struct RedisConnectionManager { + pub client: Client, timeout: Duration, } -struct RedisClusterConnectionManager { - client: ClusterClient, +pub struct RedisClusterConnectionManager { + pub client: ClusterClient, timeout: Duration, } -enum RedisPool { +pub enum RedisPool { Single(Pool), Cluster(Pool), } diff --git a/crates/store/src/backend/redis/pubsub.rs b/crates/store/src/backend/redis/pubsub.rs deleted file mode 100644 index 19159e3d..00000000 --- a/crates/store/src/backend/redis/pubsub.rs +++ /dev/null @@ -1,94 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL - */ - -use super::{RedisPool, RedisStore, into_error}; -use crate::dispatch::pubsub::{Msg, PubSubStream}; -use futures::StreamExt; -use redis::{AsyncCommands, PushInfo, cluster::ClusterConfig, cluster_async::ClusterConnection}; -use tokio::sync::mpsc::UnboundedReceiver; - -pub struct RedisPubSubStream { - stream: redis::aio::PubSubStream, -} - -pub struct RedisClusterPubSubStream { - _conn: ClusterConnection, - rx: UnboundedReceiver, -} - -impl RedisStore { - pub async fn publish(&self, topic: &'static str, message: Vec) -> trc::Result<()> { - match &self.pool { - RedisPool::Single(pool) => pool - .get() - .await - .map_err(into_error)? - .as_mut() - .publish(topic, message) - .await - .map_err(into_error), - RedisPool::Cluster(pool) => pool - .get() - .await - .map_err(into_error)? - .as_mut() - .publish(topic, message) - .await - .map_err(into_error), - } - } - - pub async fn subscribe(&self, topic: &'static str) -> trc::Result { - match &self.pool { - RedisPool::Single(pool) => { - let mut pubsub = pool - .manager() - .client - .get_async_pubsub() - .await - .map_err(into_error)?; - pubsub.subscribe(topic).await.map_err(into_error)?; - - Ok(PubSubStream::Redis(RedisPubSubStream { - stream: pubsub.into_on_message(), - })) - } - RedisPool::Cluster(pool) => { - let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); - - let mut _conn = pool - .manager() - .client - .get_async_connection_with_config(ClusterConfig::default().set_push_sender(tx)) - .await - .map_err(into_error)?; - - _conn.subscribe(topic).await.map_err(into_error)?; - - Ok(PubSubStream::RedisCluster(RedisClusterPubSubStream { - _conn, - rx, - })) - } - } - } -} - -impl RedisPubSubStream { - pub async fn next(&mut self) -> Option { - self.stream.next().await.map(Msg::Redis) - } -} - -impl RedisClusterPubSubStream { - pub async fn next(&mut self) -> Option { - loop { - if let Some(msg) = redis::Msg::from_push_info(self.rx.recv().await?) { - return Some(Msg::Redis(msg)); - } - } - } -} diff --git a/crates/store/src/config.rs b/crates/store/src/config.rs index dc508cb0..e9f378d2 100644 --- a/crates/store/src/config.rs +++ b/crates/store/src/config.rs @@ -227,11 +227,11 @@ impl Stores { { self.in_memory_stores .insert(store_id.clone(), InMemoryStore::Redis(db.clone())); - self.pubsub_stores - .insert(store_id, crate::PubSubStore::Redis(db)); + //self.pubsub_stores + // .insert(store_id, crate::PubSubStore::Redis(db)); } } - #[cfg(feature = "nats")] + /*#[cfg(feature = "nats")] "nats" => { if let Some(db) = crate::backend::nats::NatsPubSub::open(config, prefix) .await @@ -260,7 +260,7 @@ impl Stores { self.pubsub_stores .insert(store_id, crate::PubSubStore::Kafka(db)); } - } + }*/ // SPDX-SnippetBegin // SPDX-FileCopyrightText: 2020 Stalwart Labs LLC // SPDX-License-Identifier: LicenseRef-SEL diff --git a/crates/store/src/dispatch/mod.rs b/crates/store/src/dispatch/mod.rs index 5c9948e8..18558640 100644 --- a/crates/store/src/dispatch/mod.rs +++ b/crates/store/src/dispatch/mod.rs @@ -4,13 +4,12 @@ * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ -use roaring::RoaringBitmap; - use crate::Store; +use roaring::RoaringBitmap; pub mod blob; pub mod lookup; -pub mod pubsub; +pub mod registry; pub mod search; pub mod store; diff --git a/crates/store/src/dispatch/registry.rs b/crates/store/src/dispatch/registry.rs new file mode 100644 index 00000000..b6d90965 --- /dev/null +++ b/crates/store/src/dispatch/registry.rs @@ -0,0 +1,23 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ + +use registry::{schema::prelude::Registry, types::id::Id}; + +use crate::RegistryStore; + +impl RegistryStore { + pub async fn get(&self, id: Id) -> trc::Result> { + todo!() + } + + pub async fn get_or_default(&self, id: Id) -> trc::Result { + todo!() + } + + pub async fn delete(&self, id: Id) -> trc::Result<()> { + todo!() + } +} diff --git a/crates/store/src/lib.rs b/crates/store/src/lib.rs index 21a30597..13116f65 100644 --- a/crates/store/src/lib.rs +++ b/crates/store/src/lib.rs @@ -8,6 +8,7 @@ pub mod backend; pub mod config; pub mod dispatch; pub mod query; +pub mod registry; pub mod search; pub mod write; @@ -21,7 +22,7 @@ pub use xxhash_rust; use ahash::AHashMap; use backend::{fs::FsStore, http::HttpStore, memory::StaticMemoryStore}; -use std::{borrow::Cow, sync::Arc}; +use std::{borrow::Cow, path::PathBuf, sync::Arc}; use utils::config::cron::SimpleCron; use write::ValueClass; @@ -129,7 +130,6 @@ pub struct Stores { pub blob_stores: AHashMap, pub search_stores: AHashMap, pub in_memory_stores: AHashMap, - pub pubsub_stores: AHashMap, pub purge_schedules: Vec, } @@ -205,18 +205,10 @@ pub enum InMemoryStore { // SPDX-SnippetEnd } -#[derive(Clone, Default)] -pub enum PubSubStore { - #[cfg(feature = "redis")] - Redis(Arc), - #[cfg(feature = "nats")] - Nats(Arc), - #[cfg(feature = "zenoh")] - Zenoh(Arc), - #[cfg(feature = "kafka")] - Kafka(Arc), - #[default] - None, +#[derive(Clone)] +pub enum RegistryStore { + Remote(Store), + Local(PathBuf), } #[cfg(feature = "sqlite")] diff --git a/crates/store/src/registry/mod.rs b/crates/store/src/registry/mod.rs new file mode 100644 index 00000000..69b01f91 --- /dev/null +++ b/crates/store/src/registry/mod.rs @@ -0,0 +1,5 @@ +/* + * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL + */ diff --git a/crates/store/src/write/mod.rs b/crates/store/src/write/mod.rs index 200ec83f..24144def 100644 --- a/crates/store/src/write/mod.rs +++ b/crates/store/src/write/mod.rs @@ -278,6 +278,20 @@ pub enum DirectoryClass { UsedQuota(u32), } +#[derive(Debug, PartialEq, Clone, Eq, Hash)] +pub enum RegistryClass { + Item(u64), + Relation { + from: u64, + to: u64, + }, + Index { + index_id: u16, + item_id: u64, + key: Vec, + }, +} + #[derive(Debug, PartialEq, Clone, Eq, Hash)] pub enum QueueClass { Message(u64), diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 001d2d0e..460ecd33 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -13,14 +13,15 @@ postgres = ["store/postgres"] mysql = ["store/mysql"] rocks = ["store/rocks"] s3 = ["store/s3"] -redis = ["store/redis"] -nats = ["store/nats"] +redis = ["store/redis", "coordinator/redis"] +nats = ["coordinator/nats"] azure = ["store/azure"] [dev-dependencies] store = { path = "../crates/store", features = ["test_mode", "enterprise"] } nlp = { path = "../crates/nlp" } directory = { path = "../crates/directory", features = ["test_mode", "enterprise"] } +coordinator = { path = "../crates/coordinator", features = ["test_mode", "enterprise"] } jmap = { path = "../crates/jmap", features = ["test_mode", "enterprise"] } jmap_proto = { path = "../crates/jmap-proto" } imap = { path = "../crates/imap", features = ["test_mode"] }