diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml new file mode 100644 index 00000000..ba8fca8d --- /dev/null +++ b/.github/workflows/code-coverage.yml @@ -0,0 +1,36 @@ +name: Code Coverage + +on: + push: + branches: + - main + +jobs: + cover: + runs-on: ubuntu-latest + container: + image: xd009642/tarpaulin:develop-nightly + options: --security-opt seccomp=unconfined + services: + redis: + image: redis:5.0.7 + ports: + - 6379:6379 + options: --entrypoint redis-server + steps: + - uses: actions/checkout@v5 + - name: Install Protoc + uses: arduino/setup-protoc@v1 + - name: Install Redis + run: | + apt-get update + apt-get install -y redis-server + redis-server --daemonize yes + redis-cli ping + - name: Generate code coverage + run: | + cargo +nightly tarpaulin --verbose --all-features --workspace --timeout 120 --out xml + - name: Upload To codecov.io + uses: codecov/codecov-action@v3 + with: + token: ${{secrets.CODECOV_TOKEN}} \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 229eac2a..81d6fdb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 4 +version = 3 [[package]] name = "ab_glyph" @@ -20,13 +20,19 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" [[package]] name = "addr2line" -version = "0.24.2" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "adler2" version = "2.0.1" @@ -138,9 +144,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "arraydeque" @@ -374,19 +380,25 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", + "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", - "windows-targets 0.52.6", ] +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base64" version = "0.21.7" @@ -667,7 +679,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -699,18 +711,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" dependencies = [ "anstyle", "clap_lex", @@ -832,11 +844,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const_fn" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f8a2ca5ac02d09563609681103aada9e1777d54fc57a5acd7a41404f9c93b6e" + [[package]] name = "cookie" -version = "0.18.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +checksum = "fc6e25dfc584d06a3dbf775d207ff00d7de98d824c952dd2233dfbb261889a42" dependencies = [ "time", "version_check", @@ -1139,7 +1157,7 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "deboa" -version = "0.0.8" +version = "0.0.9" dependencies = [ "async-executor", "async-native-tls", @@ -1173,6 +1191,7 @@ dependencies = [ "smol-hyper", "smol-macros", "thiserror 2.0.17", + "time", "tokio", "tokio-native-tls", "url", @@ -1181,7 +1200,7 @@ dependencies = [ [[package]] name = "deboa-extras" -version = "0.0.4" +version = "0.0.5" dependencies = [ "base64 0.22.1", "brotli", @@ -1205,9 +1224,9 @@ dependencies = [ "serde", "serde-saphyr", "serde-xml-rust", - "serde_json", "smol", "smol-hyper", + "sonic-rs", "thiserror 2.0.17", "tokio", "tokio-util", @@ -1218,7 +1237,7 @@ dependencies = [ [[package]] name = "deboa-fory" -version = "0.1.2" +version = "0.1.3" dependencies = [ "deboa", "fory", @@ -1230,7 +1249,7 @@ dependencies = [ [[package]] name = "deboa-macros" -version = "0.0.6" +version = "0.0.7" dependencies = [ "deboa", "deboa-extras", @@ -1251,15 +1270,6 @@ dependencies = [ "url", ] -[[package]] -name = "deranged" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" -dependencies = [ - "powerfmt", -] - [[package]] name = "digest" version = "0.10.7" @@ -1270,6 +1280,12 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + [[package]] name = "dispatch" version = "0.2.0" @@ -1286,17 +1302,6 @@ dependencies = [ "objc2 0.6.3", ] -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "dlib" version = "0.5.2" @@ -1462,6 +1467,18 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "faststr" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baec6a0289d7f1fe5665586ef7340af82e3037207bef60f5785e57569776f0c8" +dependencies = [ + "bytes", + "rkyv", + "serde", + "simdutf8", +] + [[package]] name = "find-msvc-tools" version = "0.1.5" @@ -1475,7 +1492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.9", ] [[package]] @@ -1791,9 +1808,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.1" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "gl_generator" @@ -1872,7 +1889,7 @@ checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ "bitflags 2.10.0", "gpu-descriptor-types", - "hashbrown 0.15.5", + "hashbrown 0.15.0", ] [[package]] @@ -1959,13 +1976,14 @@ dependencies = [ [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", "num-traits", + "zerocopy", ] [[package]] @@ -1983,9 +2001,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" dependencies = [ "allocator-api2", "equivalent", @@ -2007,7 +2025,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.0", ] [[package]] @@ -2022,7 +2040,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha1", + "sha1 0.10.6", ] [[package]] @@ -2229,7 +2247,7 @@ dependencies = [ "futures", "iced_core", "log", - "semver", + "semver 1.0.27", "serde", "thiserror 2.0.17", "tokio", @@ -2418,87 +2436,6 @@ dependencies = [ "winit", ] -[[package]] -name = "icu_collections" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" -dependencies = [ - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec 1.15.1", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" - -[[package]] -name = "icu_properties" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" -dependencies = [ - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" - -[[package]] -name = "icu_provider" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" -dependencies = [ - "displaydoc", - "icu_locale_core", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2518,12 +2455,22 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279259b0ac81c89d11c290495fdcfa96ea3643b7df311c138b6fe8ca5237f0f8" +dependencies = [ + "idna_mapping", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna_mapping" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "11c13906586a4b339310541a274dd927aff6fcbb5b8e3af90634c4b31681c792" dependencies = [ - "icu_normalizer", - "icu_properties", + "unicode-joining-type", ] [[package]] @@ -2539,7 +2486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.15.0", ] [[package]] @@ -2628,9 +2575,9 @@ checksum = "72167d68f5fce3b8655487b8038691a3c9984ee769590f93f2a631f4ad64e4f5" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -2682,7 +2629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] @@ -2729,12 +2676,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" -[[package]] -name = "litemap" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" - [[package]] name = "litrs" version = "1.0.0" @@ -2763,7 +2704,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.15.0", ] [[package]] @@ -2854,6 +2795,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bcaa89828ea1e6ab547d9d61ae49f1f9336459b593f285ecc402af9152e16b2" +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2944,6 +2894,26 @@ dependencies = [ "zbus", ] +[[package]] +name = "munge" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e22e7961c873e8b305b176d2a4e1d41ce7ba31bc1c52d2a107a89568ec74c55" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ac7d860b767c6398e88fe93db73ce53eb496057aa6895ffa4d60cb02e1d1c6b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "naga" version = "27.0.3" @@ -3036,12 +3006,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - [[package]] name = "num-traits" version = "0.2.19" @@ -3464,9 +3428,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -3751,21 +3715,6 @@ dependencies = [ "vamo-macros", ] -[[package]] -name = "potential_utf" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - [[package]] name = "ppv-lite86" version = "0.2.21" @@ -3827,6 +3776,12 @@ dependencies = [ "toml_edit 0.23.5", ] +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + [[package]] name = "proc-macro2" version = "1.0.103" @@ -3842,6 +3797,26 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "quick-xml" version = "0.37.5" @@ -3915,6 +3890,15 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.5" @@ -4062,11 +4046,31 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "regex" -version = "1.12.2" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", "memchr", @@ -4076,9 +4080,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -4087,9 +4091,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "rend" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" [[package]] name = "renderdoc-sys" @@ -4126,6 +4136,35 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" +dependencies = [ + "bytes", + "hashbrown 0.15.0", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "rmp" version = "0.8.14" @@ -4172,6 +4211,15 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + [[package]] name = "rustix" version = "0.38.44" @@ -4344,6 +4392,15 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16c2f82143577edb4921b71ede051dac62ca3c16084e918bf7b40c96ae10eb33" +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.27" @@ -4354,6 +4411,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "serde" version = "1.0.228" @@ -4448,6 +4511,15 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "sha1" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4459,6 +4531,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4510,6 +4588,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "similar" version = "2.7.0" @@ -4681,12 +4765,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -4720,6 +4804,45 @@ dependencies = [ "x11rb", ] +[[package]] +name = "sonic-number" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a74044c092f4f43ca7a6cfd62854cf9fb5ac8502b131347c990bf22bef1dfe" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "sonic-rs" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4425ea8d66ec950e0a8f2ef52c766cc3d68d661d9a0845c353c40833179fd866" +dependencies = [ + "ahash", + "bumpalo", + "bytes", + "cfg-if", + "faststr", + "itoa", + "ref-cast", + "ryu", + "serde", + "simdutf8", + "sonic-number", + "sonic-simd", + "thiserror 2.0.17", +] + +[[package]] +name = "sonic-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5707edbfb34a40c9f2a55fa09a49101d9fec4e0cc171ce386086bd9616f34257" +dependencies = [ + "cfg-if", +] + [[package]] name = "spin" version = "0.5.2" @@ -4761,10 +4884,13 @@ dependencies = [ ] [[package]] -name = "stable_deref_trait" -version = "1.2.1" +name = "standback" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] [[package]] name = "static_assertions" @@ -4772,6 +4898,55 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1 0.6.1", + "syn 1.0.109", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + [[package]] name = "strict-num" version = "0.1.1" @@ -4851,17 +5026,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "sys-locale" version = "0.3.2" @@ -4970,32 +5134,40 @@ dependencies = [ [[package]] name = "time" -version = "0.3.43" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", + "const_fn", + "libc", + "standback", + "stdweb", "time-macros", + "version_check", + "winapi", ] [[package]] -name = "time-core" -version = "0.1.6" +name = "time-macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] [[package]] -name = "time-macros" -version = "0.2.24" +name = "time-macros-impl" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" dependencies = [ - "num-conv", - "time-core", + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn 1.0.109", ] [[package]] @@ -5036,16 +5208,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tinystr" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" -dependencies = [ - "displaydoc", - "zerovec", -] - [[package]] name = "tinytemplate" version = "1.2.1" @@ -5094,7 +5256,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", ] @@ -5134,9 +5296,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", @@ -5180,7 +5342,7 @@ dependencies = [ "indexmap", "toml_datetime 0.7.1", "toml_parser", - "winnow 0.7.13", + "winnow 0.7.14", ] [[package]] @@ -5189,7 +5351,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" dependencies = [ - "winnow 0.7.13", + "winnow 0.7.14", ] [[package]] @@ -5223,9 +5385,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -5289,7 +5451,7 @@ dependencies = [ "httparse", "log", "rand 0.9.2", - "sha1", + "sha1 0.10.6", "thiserror 2.0.17", "utf-8", ] @@ -5323,12 +5485,27 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "unicode-joining-type" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d00a78170970967fdb83f9d49b92f959ab2bb829186b113e4f4604ad98e180" + [[package]] name = "unicode-linebreak" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" +[[package]] +name = "unicode-normalization" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-script" version = "0.5.8" @@ -5425,8 +5602,9 @@ checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vamo" -version = "0.0.4" +version = "0.0.5" dependencies = [ + "base64 0.22.1", "deboa", "deboa-extras", "deboa-tests", @@ -5439,7 +5617,7 @@ dependencies = [ [[package]] name = "vamo-macros" -version = "0.0.4" +version = "0.0.5" dependencies = [ "deboa", "deboa-extras", @@ -5504,35 +5682,22 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if", "js-sys", @@ -5543,9 +5708,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5553,22 +5718,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn 2.0.106", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -5698,9 +5863,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -5986,7 +6151,7 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement 0.60.2", "windows-interface 0.59.3", - "windows-link 0.2.1", + "windows-link", "windows-result 0.4.1", "windows-strings 0.5.1", ] @@ -5998,7 +6163,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ "windows-core 0.62.2", - "windows-link 0.2.1", + "windows-link", "windows-threading", ] @@ -6068,12 +6233,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -6087,7 +6246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ "windows-core 0.62.2", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6114,7 +6273,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6133,7 +6292,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6178,7 +6337,7 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] @@ -6187,7 +6346,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6238,19 +6397,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -6259,7 +6418,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6282,9 +6441,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -6306,9 +6465,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -6330,9 +6489,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -6342,9 +6501,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -6366,9 +6525,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -6390,9 +6549,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -6414,9 +6573,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -6438,9 +6597,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" @@ -6505,9 +6664,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -6518,12 +6677,6 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" -[[package]] -name = "writeable" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" - [[package]] name = "ws-framer" version = "0.3.1" @@ -6630,29 +6783,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" -[[package]] -name = "yoke" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" -dependencies = [ - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - [[package]] name = "zbus" version = "5.12.0" @@ -6681,7 +6811,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow 0.7.13", + "winnow 0.7.14", "zbus_macros", "zbus_names", "zvariant", @@ -6710,7 +6840,7 @@ checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", - "winnow 0.7.13", + "winnow 0.7.14", "zvariant", ] @@ -6740,60 +6870,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "zvariant" version = "5.8.0" @@ -6803,7 +6879,7 @@ dependencies = [ "endi", "enumflags2", "serde", - "winnow 0.7.13", + "winnow 0.7.14", "zvariant_derive", "zvariant_utils", ] @@ -6831,5 +6907,5 @@ dependencies = [ "quote", "serde", "syn 2.0.106", - "winnow 0.7.13", + "winnow 0.7.14", ] diff --git a/README.md b/README.md index dbded06e..966602ac 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # deboa -[![crates.io](https://img.shields.io/crates/v/deboa?style=flat-square)](https://crates.io/crates/deboa) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) [![Documentation](https://docs.rs/deboa/badge.svg)](https://docs.rs/deboa/latest/deboa) +[![crates.io](https://img.shields.io/crates/v/deboa?style=flat-square)](https://crates.io/crates/deboa) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) [![codecov](https://codecov.io/gh/ararog/deboa/graph/badge.svg?token=T0HSBAPVSI)](https://codecov.io/gh/ararog/deboa) [![Documentation](https://docs.rs/deboa/badge.svg)](https://docs.rs/deboa/latest/deboa) ## Description @@ -56,6 +56,10 @@ async fn main() -> Result<()> { ## Subprojects +### deboa + +The core create of http client. + ### deboa-bora (removed) A crate with bora macro, for easy rest client generation. Bora macro is now part of vamo-macros. @@ -66,7 +70,7 @@ Pluggable compression/decompression, serializers and catchers. ### deboa-macros -A crate with set of convenience macros. Please note this macro no longer provides bora macro. +A crate with set of convenience macros. Please note this crate no longer provides bora macro. ### deboa-tests diff --git a/deboa-extras/Cargo.toml b/deboa-extras/Cargo.toml index 7bdaac28..117d66b9 100644 --- a/deboa-extras/Cargo.toml +++ b/deboa-extras/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deboa-extras" -version = "0.0.4" +version = "0.0.5" edition = "2021" authors = ["Rogerio Araújo "] repository = "https://github.com/ararog/deboa" @@ -8,7 +8,7 @@ homepage = "https://github.com/ararog/deboa" description = "deboa extras (serialization, compression, websockets, streams, catchers (middleware) and sse support)." readme = "README.md" license = "MIT" -keywords = ["http", "serialization", "client", "serde", "compression", "websockets", "sse"] +keywords = ["http", "serialization", "compression", "websockets", "sse"] publish = true rust-version = "1.64.0" @@ -20,7 +20,7 @@ websockets = ["dep:deboa", "dep:base64", "dep:rand", "dep:ws-framer"] # serialization serialization_all = ["json", "xml", "msgpack", "yaml", "flex"] serialization = ["json", "yaml", "flex"] -json = ["dep:serde_json", "dep:serde", "dep:http", "dep:mime", "dep:deboa"] +json = ["dep:sonic-rs", "dep:serde", "dep:http", "dep:mime", "dep:deboa"] xml = ["dep:serde-xml-rust", "dep:serde", "dep:http", "dep:mime", "dep:deboa"] msgpack = ["dep:rmp-serde", "dep:serde", "dep:http", "dep:mime", "dep:deboa"] yaml = ["dep:serde-saphyr", "dep:serde", "dep:http", "dep:mime", "dep:deboa"] @@ -39,7 +39,7 @@ smol = ["dep:smol", "dep:smol-hyper", "dep:hyper", "dep:hyper-util"] base64 = { version = "0.22.1", optional = true } brotli = { version = "8.0.2", optional = true } bytes = { version = "1.11.0", optional = true } -deboa = { path = "../deboa", version = "0.0.8", features = [ +deboa = { path = "../deboa", version = "0.0.9", features = [ "http1", "tokio-rt" ], optional = true } flate2 = { version = "1.1.5", optional = true } @@ -58,7 +58,7 @@ rmp-serde = { version = "1.3.0", optional = true } serde = { version = "1.0.217", features = ["derive"], optional = true } serde-saphyr = { version = "0.0.10", optional = true } serde-xml-rust = { version = "0.6.0", optional = true } -serde_json = { version = "1.0.138", optional = true } +sonic-rs = { version = "0.5.6", optional = true } smol = { version = "2.0.2", optional = true } smol-hyper = { version = "0.1.1", optional = true } thiserror = "2.0.17" diff --git a/deboa-extras/README.md b/deboa-extras/README.md index 8da5f85b..1b10a375 100644 --- a/deboa-extras/README.md +++ b/deboa-extras/README.md @@ -1,5 +1,8 @@ # Deboa Extras +[![Crates.io downloads](https://img.shields.io/crates/d/deboa-extras)](https://crates.io/crates/deboa-extras) [![crates.io](https://img.shields.io/crates/v/deboa-extras?style=flat-square)](https://crates.io/crates/deboa-extras) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) ![Crates.io MSRV](https://img.shields.io/crates/msrv/deboa-extras) [![Documentation](https://docs.rs/deboa-extras/badge.svg)](https://docs.rs/deboa-extras/latest/deboa-extras) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) ![Codecov](https://img.shields.io/codecov/c/github/ararog/deboa-extras) + + This crate provides additional features for Deboa like compression and serialization. ## Install diff --git a/deboa-extras/src/http/serde/json.rs b/deboa-extras/src/http/serde/json.rs index 7f98fb35..99347692 100644 --- a/deboa-extras/src/http/serde/json.rs +++ b/deboa-extras/src/http/serde/json.rs @@ -24,7 +24,7 @@ impl RequestBody for JsonBody { } fn serialize(&self, data: T) -> Result, DeboaError> { - let result = serde_json::to_vec(&data); + let result = sonic_rs::to_vec(&data); if let Err(error) = result { return Err(DeboaError::Content(ContentError::Serialization { message: error.to_string(), @@ -40,7 +40,7 @@ impl ResponseBody for JsonBody { let binding = body; let body = binding.as_ref(); - let json = serde_json::from_slice(body); + let json = sonic_rs::from_slice(body); match json { Ok(deserialized_body) => Ok(deserialized_body), diff --git a/deboa-extras/src/ws/io/socket.rs b/deboa-extras/src/ws/io/socket.rs index 39354afe..91afd291 100644 --- a/deboa-extras/src/ws/io/socket.rs +++ b/deboa-extras/src/ws/io/socket.rs @@ -79,8 +79,10 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// while let Some(message) = websocket.read_message().await { + /// println!("message: {}", message); + /// } /// ``` /// /// # Panics @@ -132,8 +134,14 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket + /// .write_message(protocol::Message::Text(message.to_string())) + /// .await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -187,8 +195,12 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket.send_close(1000, "Goodbye").await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -212,8 +224,12 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket.send_text("Hello").await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -237,8 +253,12 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket.send_binary(&[0x00, 0x01, 0x02]).await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -262,8 +282,12 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket.send_ping(&[0x00, 0x01, 0x02]).await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -287,8 +311,12 @@ impl DeboaWebSocket for WebSocket { /// /// # Examples /// - /// ```rust - /// // Example usage would go here + /// ```rust, compile_fail + /// let result = websocket.send_pong(&[0x00, 0x01, 0x02]).await; + /// if result.is_err() { + /// output.send(Event::Disconnected).await; + /// break; + /// } /// ``` /// /// # Panics @@ -301,6 +329,7 @@ impl DeboaWebSocket for WebSocket { } } +#[cfg(feature = "tokio")] impl AsyncRead for WebSocket { fn poll_read( self: Pin<&mut Self>, @@ -313,6 +342,7 @@ impl AsyncRead for WebSocket { } } +#[cfg(feature = "tokio")] impl AsyncWrite for WebSocket { fn poll_write( self: Pin<&mut Self>, @@ -361,3 +391,69 @@ impl AsyncWrite for WebSocket { .is_write_vectored() } } + +#[cfg(feature = "smol")] +impl AsyncRead for WebSocket> +where + T: hyper::rt::Read, +{ + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + Poll::Ready(Ok(0)) + } +} + +#[cfg(feature = "smol")] +impl AsyncWrite for WebSocket> +where + T: hyper::rt::Write, +{ + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + hyper::rt::Write::poll_write( + self.project() + .stream + .get_pin_mut(), + cx, + buf, + ) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + hyper::rt::Write::poll_flush( + self.project() + .stream + .get_pin_mut(), + cx, + ) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + hyper::rt::Write::poll_shutdown( + self.project() + .stream + .get_pin_mut(), + cx, + ) + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[std::io::IoSlice<'_>], + ) -> Poll> { + hyper::rt::Write::poll_write_vectored( + self.project() + .stream + .get_pin_mut(), + cx, + bufs, + ) + } +} diff --git a/deboa-extras/src/ws/mod.rs b/deboa-extras/src/ws/mod.rs index a1acb699..1989e135 100644 --- a/deboa-extras/src/ws/mod.rs +++ b/deboa-extras/src/ws/mod.rs @@ -24,8 +24,45 @@ //! .into_websocket() //! .await; //! -//! while let Ok(()) = websocket.read_message().await { -//! // Just keep checking messages +//! loop { +//! select! { +//! outgoing_message = websocket.read_message() => { +//! if let Err(message) = outgoing_message { +//! println!("Failed to read message from echo server: {}", message); +//! +//! output.send(Event::Disconnected).await; +//! break; +//! } +//! +//! match outgoing_message.unwrap() { +//! Some(message) => { +//! if let protocol::Message::Text(message) = message { +//! output +//! .send(Event::MessageReceived(Message::User( +//! format!("Server: {}", message).to_string(), +//! ))) +//! .await; +//! } +//! } +//! None => { +//! output.send(Event::Disconnected).await; +//! break; +//! } +//! } +//! } +//! +//! incoming_message = input.next() => { +//! if let Some(message) = incoming_message { +//! let result = websocket +//! .write_message(protocol::Message::Text(message.to_string())) +//! .await; +//! if result.is_err() { +//! output.send(Event::Disconnected).await; +//! break; +//! } +//! } +//! } +//! } //! } //! ``` //! diff --git a/deboa-fory/Cargo.toml b/deboa-fory/Cargo.toml index 2ac869b4..db935b11 100644 --- a/deboa-fory/Cargo.toml +++ b/deboa-fory/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deboa-fory" -version = "0.1.2" +version = "0.1.3" edition = "2021" authors = ["Rogerio Araújo "] repository = "https://github.com/ararog/deboa" @@ -12,7 +12,7 @@ keywords = ["http", "networking", "rest", "serializer", "fory"] rust-version = "1.70.0" [dependencies] -deboa = { path = "../deboa", version = "0.0.8", features = ["http1", "tokio-rt"] } +deboa = { path = "../deboa", version = "0.0.9", features = ["http1", "tokio-rt"] } fory = "0.13.2" fory-core = "0.13.1" http = "1.4.0" diff --git a/deboa-macros/Cargo.toml b/deboa-macros/Cargo.toml index bf2b8f49..3e176af5 100644 --- a/deboa-macros/Cargo.toml +++ b/deboa-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "deboa-macros" edition = "2021" -version = "0.0.6" +version = "0.0.7" authors = ["Rogerio Araújo "] description = "Request macros for the deboa HTTP client alongside bora for quick http client development" license = "MIT" @@ -20,8 +20,8 @@ xml = ["deboa-extras/xml"] msgpack = ["deboa-extras/msgpack"] [dependencies] -deboa = { path = "../deboa", version = "0.0.8", features = ["http1"] } -deboa-extras = { path = "../deboa-extras", version = "0.0.4", features = ["json"] } +deboa = { path = "../deboa", version = "0.0.9", features = ["http1"] } +deboa-extras = { path = "../deboa-extras", version = "0.0.5", features = ["json"] } serde = "1.0.228" [dev-dependencies] diff --git a/deboa-macros/README.md b/deboa-macros/README.md index d09396fa..1577752b 100644 --- a/deboa-macros/README.md +++ b/deboa-macros/README.md @@ -1,5 +1,8 @@ # Deboa Macros +[![Crates.io downloads](https://img.shields.io/crates/d/deboa-macros)](https://crates.io/crates/deboa-macros) [![crates.io](https://img.shields.io/crates/v/deboa-macros?style=flat-square)](https://crates.io/crates/deboa-macros) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) ![Crates.io MSRV](https://img.shields.io/crates/msrv/deboa-macros) [![Documentation](https://docs.rs/deboa-macros/badge.svg)](https://docs.rs/deboa-macros/latest/deboa-macros) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) ![Codecov](https://img.shields.io/codecov/c/github/ararog/deboa-macros) + + **deboa-macros** is a collection of macros for deboa. It used to be the home of bora macro, which has been moved to its own crate but it will continue to exist in this crate for backwards compatibility. diff --git a/deboa/Cargo.toml b/deboa/Cargo.toml index 6e45d17a..4c7c8a51 100644 --- a/deboa/Cargo.toml +++ b/deboa/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "deboa" -version = "0.0.8" +version = "0.0.9" edition = "2021" authors = ["Rogerio Araújo "] repository = "https://github.com/ararog/deboa" @@ -43,7 +43,7 @@ async-native-tls = { version = "0.5.0", optional = true } async-trait = "0.1.89" base64 = "0.22.1" bytes = { version = "1.11", optional = false } -cookie = "0.18.1" +cookie = "0.15.2" futures = "0.3.31" h3 = { version = "0.0.6", optional = true } h3-quinn = { version = "0.0.5", optional = true } @@ -70,6 +70,7 @@ smol = { version = "2.0.2", optional = true } smol-hyper = { version = "0.1.0", optional = true, features = ["smol"] } smol-macros = { version = "0.1.1", optional = true } thiserror = "2.0.17" +time = "=0.2.27" tokio = { version = "1.47.2", features = ["macros", "rt-multi-thread"], optional = true } tokio-native-tls = { version = "0.3.1", optional = true } url = "2.5.4" diff --git a/deboa/README.md b/deboa/README.md index 4a7226ec..8db6ef51 100644 --- a/deboa/README.md +++ b/deboa/README.md @@ -1,6 +1,8 @@ # deboa -[![crates.io](https://img.shields.io/crates/v/deboa?style=flat-square)](https://crates.io/crates/deboa) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) [![Documentation](https://docs.rs/deboa/badge.svg)](https://docs.rs/deboa/latest/deboa) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) +[![Crates.io downloads](https://img.shields.io/crates/d/deboa)](https://crates.io/crates/deboa) [![crates.io](https://img.shields.io/crates/v/deboa?style=flat-square)](https://crates.io/crates/deboa) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) ![Crates.io MSRV](https://img.shields.io/crates/msrv/deboa) [![Documentation](https://docs.rs/deboa/badge.svg)](https://docs.rs/deboa/latest/deboa) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) [![codecov](https://codecov.io/gh/ararog/deboa/graph/badge.svg?token=T0HSBAPVSI)](https://codecov.io/gh/ararog/deboa) + + ## Description diff --git a/deboa/src/cookie.rs b/deboa/src/cookie.rs index 157c83a4..5db24dba 100644 --- a/deboa/src/cookie.rs +++ b/deboa/src/cookie.rs @@ -16,7 +16,7 @@ //! //! ```rust //! use deboa::cookie::DeboaCookie; -//! use cookie::time::Duration; +//! use time::Duration; //! //! // Create a simple session cookie //! let mut cookie = DeboaCookie::new("session_id", "abc123"); diff --git a/deboa/src/response.rs b/deboa/src/response.rs index 588c92b6..c0494ff7 100644 --- a/deboa/src/response.rs +++ b/deboa/src/response.rs @@ -83,17 +83,18 @@ use std::fs::write; use http::{header, HeaderName, HeaderValue, Response}; use http_body_util::{BodyDataStream, BodyExt, Either, Full}; -use hyper::body::{Bytes, Incoming}; -use hyper::upgrade::on; +use hyper::{ + body::{Bytes, Incoming}, + upgrade::on, +}; #[cfg(feature = "tokio-rt")] use hyper_util::rt::TokioIo; use serde::Deserialize; #[cfg(feature = "smol-rt")] use smol_hyper::rt::FuturesIo; -use crate::cookie::DeboaCookie; -use crate::errors::{ConnectionError, IoError}; -use crate::{client::serde::ResponseBody, errors::DeboaError, Result}; +use crate::errors::{ConnectionError, DeboaError, IoError}; +use crate::{client::serde::ResponseBody, cookie::DeboaCookie, Result}; use url::Url; pub type DeboaBody = Either>; @@ -684,14 +685,16 @@ impl DeboaResponse { #[cfg(feature = "smol-rt")] pub async fn upgrade(self) -> Result> { if self.inner.version() != http::Version::HTTP_11 { - return Err(DeboaError::Io { + return Err(DeboaError::Connection(ConnectionError::Upgrade { message: "Upgrade is only supported for HTTP/1.1".to_string(), - }); + })); } let upgrade = on(self.inner).await; if let Err(e) = upgrade { - return Err(DeboaError::Io { message: e.to_string() }); + return Err(DeboaError::Connection(ConnectionError::Upgrade { + message: e.to_string(), + })); } Ok(FuturesIo::new(upgrade.unwrap())) } diff --git a/deboa/src/rt/smol/http1.rs b/deboa/src/rt/smol/http1.rs index ceef93b4..02af93c0 100644 --- a/deboa/src/rt/smol/http1.rs +++ b/deboa/src/rt/smol/http1.rs @@ -13,7 +13,7 @@ use url::Url; use crate::{ cert::ClientCert, client::conn::http::{BaseHttpConnection, DeboaHttpConnection, Http1Request}, - errors::DeboaError, + errors::{ConnectionError, DeboaError}, rt::smol::stream::SmolStream, Result, }; @@ -50,10 +50,10 @@ impl DeboaHttpConnection for BaseHttpConnection { }; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tcp { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); @@ -69,10 +69,10 @@ impl DeboaHttpConnection for BaseHttpConnection { }; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tcp { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); @@ -95,19 +95,19 @@ impl DeboaHttpConnection for BaseHttpConnection { .await; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tls { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); SmolStream::Tls(stream) } scheme => { - return Err(DeboaError::UnsupportedScheme { + return Err(DeboaError::Connection(ConnectionError::UnsupportedScheme { message: format!("unsupported scheme: {scheme:?}"), - }); + })); } } }; @@ -143,3 +143,5 @@ impl DeboaHttpConnection for BaseHttpConnection { .await } } + +impl crate::client::conn::http::private::Sealed for BaseHttpConnection {} diff --git a/deboa/src/rt/smol/http2.rs b/deboa/src/rt/smol/http2.rs index 648e5ab7..45b4e499 100644 --- a/deboa/src/rt/smol/http2.rs +++ b/deboa/src/rt/smol/http2.rs @@ -13,7 +13,7 @@ use url::Url; use crate::{ cert::ClientCert, client::conn::http::{BaseHttpConnection, DeboaHttpConnection, Http2Request}, - errors::DeboaError, + errors::{ConnectionError, DeboaError}, rt::smol::{executor::SmolExecutor, stream::SmolStream}, Result, }; @@ -50,10 +50,10 @@ impl DeboaHttpConnection for BaseHttpConnection { }; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tcp { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); @@ -69,10 +69,10 @@ impl DeboaHttpConnection for BaseHttpConnection { }; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tcp { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); @@ -94,19 +94,19 @@ impl DeboaHttpConnection for BaseHttpConnection { .await; if let Err(e) = stream { - return Err(DeboaError::Connection { + return Err(DeboaError::Connection(ConnectionError::Tls { host: host.to_string(), message: e.to_string(), - }); + })); } let stream = stream.unwrap(); SmolStream::Tls(stream) } scheme => { - return Err(DeboaError::UnsupportedScheme { + return Err(DeboaError::Connection(ConnectionError::UnsupportedScheme { message: format!("unsupported scheme: {scheme:?}"), - }); + })); } } }; @@ -139,3 +139,5 @@ impl DeboaHttpConnection for BaseHttpConnection { .await } } + +impl crate::client::conn::http::private::Sealed for BaseHttpConnection {} diff --git a/deboa/src/tests/cookie.rs b/deboa/src/tests/cookie.rs index d8983cb6..fe7ff0b7 100644 --- a/deboa/src/tests/cookie.rs +++ b/deboa/src/tests/cookie.rs @@ -1,4 +1,5 @@ -use cookie::{time::OffsetDateTime, Expiration}; +use cookie::Expiration; +use time::OffsetDateTime; use crate::cookie::DeboaCookie; diff --git a/deboa/src/tests/request.rs b/deboa/src/tests/request.rs index 33d9270d..d1c0d2d0 100644 --- a/deboa/src/tests/request.rs +++ b/deboa/src/tests/request.rs @@ -1,6 +1,9 @@ use std::{str::FromStr, sync::Arc}; -use crate::{request::DeboaRequest, request::FetchWith, Deboa, Result}; +use crate::{ + request::{DeboaRequest, FetchWith, IntoRequest}, + Deboa, Result, +}; use deboa_tests::utils::JSONPLACEHOLDER; use http::{header, HeaderValue, Method}; @@ -19,6 +22,30 @@ fn test_into_url() -> Result<()> { Ok(()) } +#[test] +fn test_into_request_from_str() -> Result<()> { + let request = JSONPLACEHOLDER.into_request()?; + assert_eq!( + request + .url() + .to_string(), + JSONPLACEHOLDER + ); + Ok(()) +} + +#[test] +fn test_into_request_from_string() -> Result<()> { + let request = format!("{}/posts/{}", JSONPLACEHOLDER, 1).into_request()?; + assert_eq!( + request + .url() + .to_string(), + format!("{}/posts/{}", JSONPLACEHOLDER, 1) + ); + Ok(()) +} + #[test] fn test_into_str() -> Result<()> { let request = DeboaRequest::get(JSONPLACEHOLDER)?.build()?; diff --git a/vamo-macros/Cargo.toml b/vamo-macros/Cargo.toml index cab9c6e1..2b580283 100644 --- a/vamo-macros/Cargo.toml +++ b/vamo-macros/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "vamo-macros" edition = "2021" -version = "0.0.4" +version = "0.0.5" authors = ["Rogerio Araújo "] description = "macros for vamo to automate resource trait generation" license = "MIT" @@ -22,9 +22,9 @@ msgpack = ["deboa-extras/msgpack"] proc-macro = true [dependencies] -deboa = { path = "../deboa", version = "0.0.8", features = ["http1"] } -deboa-extras = { path = "../deboa-extras", version = "0.0.4", features=["json"] } -vamo = { path = "../vamo", version = "0.0.4" } +deboa = { path = "../deboa", version = "0.0.9", features = ["http1"] } +deboa-extras = { path = "../deboa-extras", version = "0.0.5", features=["json"] } +vamo = { path = "../vamo", version = "0.0.5" } proc-macro2 = "1.0.103" serde = "1.0.228" syn = { version = "2.0", features = ["full"] } diff --git a/vamo-macros/README.md b/vamo-macros/README.md index 3b217a9c..72da4410 100644 --- a/vamo-macros/README.md +++ b/vamo-macros/README.md @@ -1,6 +1,8 @@ - # Vamo Macros +[![Crates.io downloads](https://img.shields.io/crates/d/vamo-macros)](https://crates.io/crates/vamo-macros) [![crates.io](https://img.shields.io/crates/v/vamo-macros?style=flat-square)](https://crates.io/crates/vamo-macros) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) ![Crates.io MSRV](https://img.shields.io/crates/msrv/vamo-macros) [![Documentation](https://docs.rs/vamo-macros/badge.svg)](https://docs.rs/vamo-macros/latest/vamo-macros) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) ![Codecov](https://img.shields.io/codecov/c/github/ararog/deboa) + + Vamo macros is a collection of macros to make possible use structs as resources to be sent over vamo as client. diff --git a/vamo-macros/src/bora/config/delete.rs b/vamo-macros/src/bora/config/delete.rs deleted file mode 100644 index d9d62961..00000000 --- a/vamo-macros/src/bora/config/delete.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::collections::HashMap; - -use proc_macro::TokenStream; -use quote::ToTokens; -use syn::{parse_macro_input, parse_str, punctuated::Punctuated, Pat, PatType, Token, TraitItemFn, Visibility}; -use crate::parser::{operations::delete::{DeleteFieldEnum}}; -use crate::parser::utils::extract_params_from_path; - -pub fn delete(attr: TokenStream, item: TokenStream) -> TokenStream { - let attrs = parse_macro_input!(attr with Punctuated::parse_terminated); - let item = parse_macro_input!(item as TraitItemFn); - - let path_fields = attrs.iter().fold(HashMap::new(), |mut acc, field| { - if let DeleteFieldEnum::path(path) = field { - let params = extract_params_from_path(&path.value.value()); - for param in params { - acc.insert(param.0, param.1); - } - } - acc - }); - - if item.sig.asyncness.is_none() { - panic!("expected to be an async function"); - } - - item.sig.inputs.iter().for_each(|input| { - if let syn::FnArg::Typed(typed) = input { - let PatType { attrs: _, pat, colon_token: _, ty } = typed; - if let Pat::Ident(ident) = &**pat { - if ! path_fields.contains_key(&ident.ident.to_string()) { - panic!("expected to have a parameter named {}", ident.ident); - } - - let param_type = path_fields.get(&ident.ident.to_string()).unwrap(); - if *ty.as_ref() != parse_str::(param_type).unwrap() { - panic!("expected type {param_type}"); - } - } - } - }); - - item.to_token_stream().into() -} diff --git a/vamo-macros/src/bora/mod.rs b/vamo-macros/src/bora/mod.rs index ef9243fa..302b178b 100644 --- a/vamo-macros/src/bora/mod.rs +++ b/vamo-macros/src/bora/mod.rs @@ -62,8 +62,8 @@ //! ``` //! -mod config; -mod parser; -mod token; +pub(crate) mod config; +pub(crate) mod parser; +pub(crate) mod token; pub use config::api::bora; diff --git a/vamo-macros/tests/bora/delete.rs b/vamo-macros/tests/bora/delete.rs new file mode 100644 index 00000000..95b1010c --- /dev/null +++ b/vamo-macros/tests/bora/delete.rs @@ -0,0 +1,18 @@ +use deboa_tests::utils::JSONPLACEHOLDER; +use vamo::Vamo; +use vamo_macros::bora; + +#[bora(api(delete(name = "delete_post", path = "/posts/")))] +pub struct PostService; + +#[tokio::test] +async fn test_delete_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + post_service + .delete_post(1) + .await?; + Ok(()) +} diff --git a/vamo-macros/tests/bora/get.rs b/vamo-macros/tests/bora/get.rs new file mode 100644 index 00000000..42738910 --- /dev/null +++ b/vamo-macros/tests/bora/get.rs @@ -0,0 +1,86 @@ +use deboa_tests::utils::JSONPLACEHOLDER; +use vamo::Vamo; +use vamo_macros::bora; + +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct Post { + pub id: u32, + pub title: String, +} + +#[bora( + api( + get(name="get_all", path="/posts", res_body=Vec, format="json"), + get(name="get_by_id", path="/posts/", res_body=Post, format="json"), + get(name="query_by_id", path="/posts?", res_body=Vec, format="json"), + get(name="query_by_title", path="/posts?&", res_body=Vec, format="json") + ) + )] +pub struct PostService; + +#[tokio::test] +async fn test_get_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + let post = post_service + .get_by_id(1) + .await?; + + println!("id...: {}", post.id); + println!("title: {}", post.title); + + assert_eq!(post.id, 1); + Ok(()) +} + +#[tokio::test] +async fn test_get_all() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + let posts = post_service + .get_all() + .await?; + + println!("posts: {posts:?}"); + + assert_eq!(posts.len(), 100); + Ok(()) +} + +#[tokio::test] +async fn test_query_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + let posts = post_service + .query_by_id(1) + .await?; + + println!("posts: {posts:?}"); + + assert_eq!(posts.len(), 1); + Ok(()) +} + +#[tokio::test] +async fn test_query_by_title() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + let posts = post_service + .query_by_title(6, "dolorem eum magni eos aperiam quia") + .await?; + + println!("posts: {posts:?}"); + + assert_eq!(posts.len(), 1); + Ok(()) +} diff --git a/vamo-macros/tests/bora/mod.rs b/vamo-macros/tests/bora/mod.rs new file mode 100644 index 00000000..1fbc1f28 --- /dev/null +++ b/vamo-macros/tests/bora/mod.rs @@ -0,0 +1,5 @@ +mod delete; +mod get; +mod patch; +mod post; +mod put; diff --git a/vamo-macros/tests/bora/patch.rs b/vamo-macros/tests/bora/patch.rs new file mode 100644 index 00000000..d03e4d56 --- /dev/null +++ b/vamo-macros/tests/bora/patch.rs @@ -0,0 +1,31 @@ +use deboa_tests::utils::JSONPLACEHOLDER; +use serde::{Deserialize, Serialize}; +use vamo::Vamo; +use vamo_macros::bora; + +#[derive(Serialize, Deserialize)] +pub struct Post { + pub title: String, + pub body: String, + #[serde(rename = "userId")] + pub user_id: u32, +} + +#[bora( + api( + patch(name="patch_post", path="/posts/", req_body=Post, format="json"), + ) + )] +pub struct PostService; + +#[tokio::test] +async fn test_patch_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + post_service + .patch_post(1, Post { title: "title".to_string(), body: "body".to_string(), user_id: 1 }) + .await?; + Ok(()) +} diff --git a/vamo-macros/tests/bora/post.rs b/vamo-macros/tests/bora/post.rs new file mode 100644 index 00000000..30031f08 --- /dev/null +++ b/vamo-macros/tests/bora/post.rs @@ -0,0 +1,37 @@ +use deboa_tests::utils::JSONPLACEHOLDER; +use serde::{Deserialize, Serialize}; +use vamo::Vamo; +use vamo_macros::bora; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Post { + pub id: u32, + pub title: String, + pub body: String, + #[serde(rename = "userId")] + pub user_id: u32, +} + +#[bora( + api( + post(name="create_post", path="/posts", req_body=Post, format="json"), + ) + )] +pub struct PostService; + +#[tokio::test] +async fn test_get_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + post_service + .create_post(Post { + id: 1, + title: "title".to_string(), + body: "body".to_string(), + user_id: 1, + }) + .await?; + Ok(()) +} diff --git a/vamo-macros/tests/bora/put.rs b/vamo-macros/tests/bora/put.rs new file mode 100644 index 00000000..c2e7fb1e --- /dev/null +++ b/vamo-macros/tests/bora/put.rs @@ -0,0 +1,31 @@ +use deboa_tests::utils::JSONPLACEHOLDER; +use serde::{Deserialize, Serialize}; +use vamo::Vamo; +use vamo_macros::bora; + +#[derive(Serialize, Deserialize, Debug)] +pub struct Post { + pub title: String, + pub body: String, + #[serde(rename = "userId")] + pub user_id: u32, +} + +#[bora( + api( + put(name="update_post", path="/posts/", req_body=Post, format="json"), + ) + )] +pub struct PostService; + +#[tokio::test] +async fn test_put_by_id() -> Result<()> { + let client = Vamo::new(JSONPLACEHOLDER)?; + + let mut post_service = PostService::new(client); + + post_service + .update_post(1, Post { title: "title".to_string(), body: "body".to_string(), user_id: 1 }) + .await?; + Ok(()) +} diff --git a/vamo-macros/tests/mod.rs b/vamo-macros/tests/mod.rs index bc7c83c0..da210f01 100644 --- a/vamo-macros/tests/mod.rs +++ b/vamo-macros/tests/mod.rs @@ -1 +1,2 @@ -mod derive; +mod bora; +mod resource; diff --git a/vamo-macros/tests/derive.rs b/vamo-macros/tests/resource/mod.rs similarity index 100% rename from vamo-macros/tests/derive.rs rename to vamo-macros/tests/resource/mod.rs diff --git a/vamo/Cargo.toml b/vamo/Cargo.toml index aa17cf33..de892bd5 100644 --- a/vamo/Cargo.toml +++ b/vamo/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vamo" -version = "0.0.4" +version = "0.0.5" edition = "2021" authors = ["Rogerio Araújo "] repository = "https://github.com/ararog/deboa" @@ -13,8 +13,9 @@ publish = true rust-version = "1.64.0" [dependencies] -deboa = { path = "../deboa", version = "0.0.8", features = ["http1"] } -deboa-extras = { path = "../deboa-extras", version = "0.0.4", features = ["json"] } +base64 = "0.22.1" +deboa = { path = "../deboa", version = "0.0.9", features = ["http1"] } +deboa-extras = { path = "../deboa-extras", version = "0.0.5", features = ["json"] } http = "1.4.0" serde = "1.0.228" url = "2.5.7" diff --git a/vamo/README.md b/vamo/README.md index 96fd6324..60e99149 100644 --- a/vamo/README.md +++ b/vamo/README.md @@ -1,5 +1,8 @@ # Vamo +[![Crates.io downloads](https://img.shields.io/crates/d/vamo)](https://crates.io/crates/vamo) [![crates.io](https://img.shields.io/crates/v/vamo?style=flat-square)](https://crates.io/crates/vamo) [![Build Status](https://github.com/ararog/deboa/actions/workflows/rust.yml/badge.svg?event=push)](https://github.com/ararog/deboa/actions/workflows/rust.yml) ![Crates.io MSRV](https://img.shields.io/crates/msrv/vamo) [![Documentation](https://docs.rs/vamo/badge.svg)](https://docs.rs/vamo/latest/vamo) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ararog/deboa/blob/main/LICENSE.md) ![Codecov](https://img.shields.io/codecov/c/github/ararog/deboa) + + **vamo** ("Let's go" in portuguese) is a rest wrapper for deboa. Vamo is a key part of the deboa ecosystem, allowing bora macro to generate api clients. ## Usage diff --git a/vamo/src/lib.rs b/vamo/src/lib.rs index 284a9b79..523f84df 100644 --- a/vamo/src/lib.rs +++ b/vamo/src/lib.rs @@ -1,54 +1,79 @@ //! # Vamo: A High-Level HTTP Client for Deboa //! -//! `vamo` provides a more ergonomic, high-level API on top of the `deboa` HTTP client, -//! making it easier to work with RESTful APIs and other HTTP services. +//! `vamo` provides an ergonomic, high-level API on top of the `deboa` HTTP client, +//! making it easier to work with RESTful APIs and other HTTP services. It offers +//! a more intuitive interface for building and sending HTTP requests while maintaining +//! full compatibility with the underlying `deboa` client. //! //! ## Features //! -//! - **Simplified API**: Chainable methods for building and sending requests -//! - **Base URL Management**: Automatically handles URL construction -//! - **Resource-Oriented**: Work with API resources in a more natural way -//! - **Seamless Integration**: Fully compatible with `deboa` and `deboa-extras` +//! - **Fluent API**: Chainable methods for building and sending requests +//! - **Resource-Oriented**: First-class support for REST resources with the `Resource` trait +//! - **Authentication**: Built-in support for common authentication methods +//! - **Type Safety**: Strong typing for request/response bodies +//! - **Flexible**: Works with any HTTP method and content type +//! - **Async by Default**: Built on top of async/await for high performance //! //! ## Getting Started //! -//! Add `vamo` to your `Cargo.toml`: +//! Add `vamo` and its dependencies to your `Cargo.toml`: //! //! ```toml //! [dependencies] //! vamo = { version = "0.1", path = "../vamo" } //! deboa = { version = "0.1", path = ".." } //! deboa-extras = { version = "0.1", path = "../deboa-extras" } +//! serde = { version = "1.0", features = ["derive"] } +//! tokio = { version = "1.0", features = ["full"] } //! ``` //! //! ## Basic Usage //! -//! ```compile_fail +//! ### Making Simple Requests +//! +//! ```no_run, compile_fail //! use vamo::Vamo; //! use deboa_extras::http::serde::json::JsonBody; //! //! #[tokio::main] //! async fn main() -> Result<(), Box> { -//! // Create a new Vamo client with a base URL -//! let mut vamo = Vamo::new("https://api.example.com")?; +//! // Create a new Vamo client with a base URL +//! let mut vamo = Vamo::new("https://api.example.com")?; //! -//! // Make a GET request -//! let user: serde_json::Value = vamo -//! .get("/users/1")? -//! .send() -//! .await? -//! .body_as(JsonBody) -//! .await?; +//! // Make a GET request +//! let response = vamo +//! .get("/users/1")? +//! .send() +//! .await?; +//! +//! // Parse response as JSON +//! let user: User = response.body_as(JsonBody).await?; +//! println!("User: {:?}", user); //! -//! println!("User: {:?}", user); -//! Ok(()) +//! // Make a POST request with JSON body +//! let new_user = json!({ +//! "name": "John Doe", +//! "email": "john@example.com" +//! }); +//! +//! let response = vamo +//! .post("/users")? +//! .body_as(JsonBody, &new_user)? +//! .send() +//! .await?; +//! +//! println!("Created user: {:?}", response.status()); +//! Ok(()) //! } //! ``` //! //! ## Working with Resources //! -//! ```compile_fail -//! use vamo::{Vamo, resource::Resource}; +//! Vamo provides a `Resource` trait that makes it easy to work with REST resources: +//! +//! ```no_run +//! use vamo::{Vamo, resource::{Resource, ResourceMethod}}; +//! use deboa_extras::http::serde::json::JsonBody; //! use serde::{Deserialize, Serialize}; //! //! #[derive(Debug, Serialize, Deserialize)] @@ -59,48 +84,139 @@ //! } //! //! impl Resource for User { +//! // Return the resource ID as a string //! fn id(&self) -> String { //! self.id.map(|id| id.to_string()).unwrap_or_default() //! } //! -//! fn name(&self) -> &str { "users" } +//! // Return the base path for this resource (e.g., "users") +//! fn name(&self) -> &str { +//! "users" +//! } //! -//! fn body_type(&self) -> impl RequestBody { +//! // Specify how to serialize this resource +//! fn body_type(&self) -> impl deboa::client::serde::RequestBody { //! JsonBody //! } //! } //! //! #[tokio::main] //! async fn main() -> Result<(), Box> { -//! let mut vamo = Vamo::new("https://api.example.com")?; -//! let mut users = User { -//! id: None, -//! name: String::new(), -//! email: String::new(), -//! }; -//! // List all users -//! let all_users: Vec = vamo.load(&mut users).await?; -//! -//! // Create a new user -//! let new_user = User { -//! id: None, -//! name: "John Doe".to_string(), -//! email: "john@example.com".to_string(), -//! }; -//! let created: User = vamo.create(&new_user).await?; -//! Ok(()) +//! let mut vamo = Vamo::new("https://api.example.com")?; +//! +//! // List all users +//! let mut user_template = User { +//! id: None, +//! name: String::new(), +//! email: String::new(), +//! }; +//! +//! let users: Vec = vamo +//! .load(&mut user_template)? +//! .send() +//! .await? +//! .body_as(JsonBody) +//! .await?; +//! println!("All users: {:?}", users); +//! +//! // Create a new user +//! let mut new_user = User { +//! id: None, +//! name: "John Doe".to_string(), +//! email: "john@example.com".to_string(), +//! }; +//! +//! let created: User = vamo +//! .create(&mut new_user)? +//! .send() +//! .await? +//! .body_as(JsonBody) +//! .await?; +//! println!("Created user: {:?}", created); +//! +//! // Update a user +//! let mut updated_user = User { +//! id: created.id, +//! name: "John Updated".to_string(), +//! email: created.email, +//! }; +//! +//! let updated: User = vamo +//! .update(&mut updated_user)? +//! .send() +//! .await? +//! .body_as(JsonBody) +//! .await?; +//! println!("Updated user: {:?}", updated); +//! +//! // Delete a user +//! vamo.remove(&mut updated_user)?.send().await?; +//! println!("User deleted"); +//! +//! Ok(()) //! } //! ``` - +//! +//! ## Authentication +//! +//! Vamo provides convenience methods for common authentication methods: +//! +//! ```no_run, compile_fail +//! # use vamo::Vamo; +//! # fn main() -> Result<(), Box> { +//! // Bearer token authentication +//! let mut vamo = Vamo::new("https://api.example.com")?; +//! vamo +//! .get("/users/1") +//! .bearer_auth("your-token-here") +//! .send() +//! .await?; +//! +//! // Basic authentication +//! let mut vamo = Vamo::new("https://api.example.com")?; +//! vamo +//! .get("/users/1") +//! .basic_auth("username", "password") +//! .send() +//! .await?; +//! # Ok(()) } +//! ``` +//! +//! ## Error Handling +//! +//! Vamo uses the `deboa::Result` type for error handling, which provides detailed +//! error information including: +//! - Network errors +//! - Serialization/deserialization errors +//! - HTTP protocol errors +//! - URL parsing errors +//! +//! ## Examples +//! +//! Check the `examples/` directory for more comprehensive examples of using Vamo +//! with different types of APIs and authentication methods. +//! +//! ## License +//! +//! MIT license +//! +//! ## Author +//! +//! Rogerio Pacheco use std::sync::Arc; use crate::resource::{Resource, ResourceMethod}; +use base64::{engine::general_purpose::STANDARD, Engine as _}; use deboa::{ - client::serde::RequestBody, request::DeboaRequest, response::DeboaResponse, url::IntoUrl, + client::serde::RequestBody, + errors::{DeboaError, RequestError}, + request::DeboaRequest, + response::DeboaResponse, + url::IntoUrl, Deboa, Result, }; use http::{ - header::{CONTENT_TYPE, HOST}, + header::{self, CONTENT_TYPE, HOST}, HeaderMap, HeaderName, HeaderValue, Method, }; use serde::Serialize; @@ -111,6 +227,7 @@ pub mod resource; #[cfg(test)] mod tests; +/// A builder for HTTP requests. pub struct Vamo { client: Deboa, base_url: Url, @@ -121,19 +238,54 @@ pub struct Vamo { } impl Vamo { + /// Create a new Vamo instance. + /// + /// # Arguments + /// + /// * `url` - The base URL for the requests. + /// + /// # Returns + /// + /// * `Result` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/path").send().await?; + /// ``` + /// + /// # Panics + /// + /// If the URL is invalid, or headers are invalid, the function will panic. + /// pub fn new(url: U) -> Result { let base_url = url.into_url()?; let mut headers = HeaderMap::new(); - headers.insert( - HOST, - HeaderValue::from_str( - base_url - .host_str() - .unwrap(), - ) - .unwrap(), + let host = base_url.host_str(); + if host.is_none() { + return Err(DeboaError::Request(RequestError::UrlParse { + message: "Invalid URL: Missing host.".to_string(), + })); + } + + let host_header = HeaderValue::from_str( + base_url + .host_str() + .unwrap(), ); - headers.insert(CONTENT_TYPE, HeaderValue::from_str("application/json").unwrap()); + if let Err(e) = host_header { + return Err(DeboaError::Header { message: e.to_string() }); + } + + headers.insert(HOST, host_header.unwrap()); + + let content_type_header = HeaderValue::from_str("application/json"); + if let Err(e) = content_type_header { + return Err(DeboaError::Header { message: e.to_string() }); + } + + headers.insert(CONTENT_TYPE, content_type_header.unwrap()); Ok(Vamo { client: Deboa::new(), @@ -145,17 +297,59 @@ impl Vamo { }) } + /// Set the client to be used for requests. + /// + /// # Arguments + /// + /// * `client` - The client to be used for requests. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + #[inline] pub fn client(&mut self, client: Deboa) -> &mut Self { self.client = client; self } + /// Set a header for the request. + /// + /// # Arguments + /// + /// * `key` - The header key. + /// * `value` - The header value. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/api") + /// .header("Content-Type", "application/json") + /// .send() + /// .await?; + /// ``` + #[inline] pub fn header(&mut self, key: HeaderName, value: &str) -> &mut Self { self.headers .insert(key, HeaderValue::from_str(value).unwrap()); self } + /// Set the body of the request. + /// + /// # Arguments + /// + /// * `body_type` - The type of the body. + /// * `body` - The body to be set. + /// + /// # Returns + /// + /// * `Result<&mut Self>` - The builder. + #[inline] pub fn body_as( &mut self, body_type: T, @@ -167,36 +361,198 @@ impl Vamo { Ok(self) } + /// Set the method of the request. + /// + /// # Arguments + /// + /// * `path` - The path of the request. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/path").send().await?; + /// ``` + #[inline] pub fn get(&mut self, path: &str) -> &mut Self { self.path = path.to_string(); self.method = Method::GET; self } + /// Set the method of the request. + /// + /// # Arguments + /// + /// * `path` - The path of the request. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.post("/path").body_as(JSON, body).send().await?; + /// ``` + #[inline] pub fn post(&mut self, path: &str) -> &mut Self { self.path = path.to_string(); self.method = Method::POST; self } + /// Set the method of the request. + /// + /// # Arguments + /// + /// * `path` - The path of the request. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.put("/path/1").body_as(JSON, body).send().await?; + /// ``` + #[inline] pub fn put(&mut self, path: &str) -> &mut Self { self.path = path.to_string(); self.method = Method::PUT; self } + /// Set the method of the request. + /// + /// # Arguments + /// + /// * `path` - The path of the request. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.patch("/path/1").body_as(JsonBody, body).send().await?; + /// ``` + #[inline] + pub fn patch(&mut self, path: &str) -> &mut Self { + self.path = path.to_string(); + self.method = Method::PATCH; + self + } + + /// Set the method of the request. + /// + /// # Arguments + /// + /// * `path` - The path of the request. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.delete("/path/1").send().await?; + /// ``` + #[inline] pub fn delete(&mut self, path: &str) -> &mut Self { self.path = path.to_string(); self.method = Method::DELETE; self } - pub fn patch(&mut self, path: &str) -> &mut Self { - self.path = path.to_string(); - self.method = Method::PATCH; + /// Set the bearer token for the request. + /// + /// # Arguments + /// + /// * `token` - The bearer token. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/api") + /// .bearer_auth("your-token-here") + /// .send() + /// .await?; + /// ``` + #[inline] + pub fn bearer_auth(&mut self, token: &str) -> &mut Self { + self.header(header::AUTHORIZATION, format!("Bearer {token}").as_str()); + self + } + + /// Set the basic authentication for the request. + /// + /// # Arguments + /// + /// * `username` - The username. + /// * `password` - The password. + /// + /// # Returns + /// + /// * `&mut Self` - The builder. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/api") + /// .basic_auth("username", "password") + /// .send() + /// .await?; + /// ``` + #[inline] + pub fn basic_auth(&mut self, username: &str, password: &str) -> &mut Self { + self.header( + header::AUTHORIZATION, + format!("Basic {}", STANDARD.encode(format!("{username}:{password}"))).as_str(), + ); self } + /// Send the request. + /// + /// # Returns + /// + /// * `Result` - The response. + /// + /// # Errors + /// + /// * `DeboaError` - The error. + /// + /// # Examples + /// + /// ``` rust, compile_fail + /// let mut vamo = Vamo::new("https://api.example.com")?; + /// let response = vamo.get("/path").send().await?; + /// ``` + /// + /// # Notes + /// + /// * The request is sent using the `Deboa` client. + /// * The response is returned as a `DeboaResponse`. + /// + #[inline] pub async fn send(&mut self) -> Result { let mut base_url = self .base_url