diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 36e0278..faf1e62 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -20,7 +20,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: 1.70.0 + toolchain: 1.78.0 override: true - name: Publish crate to crates.io diff --git a/Cargo.lock b/Cargo.lock index cfc0640..6316ec0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,13 +19,14 @@ checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.7.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ - "getrandom 0.2.15", + "cfg-if", "once_cell", "version_check", + "zerocopy 0.7.35", ] [[package]] @@ -37,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anes" version = "0.1.6" @@ -45,16 +52,16 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", + "is_terminal_polyfill", "utf8parse", ] @@ -84,12 +91,12 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -140,9 +147,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "aws-credential-types" -version = "0.57.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb9073c88dbf12f68ce7d0e149f989627a1d1ae3d2b680459f04ccc29d1cbd0f" +checksum = "60e8f6b615cb5fc60a98132268508ad104310f0cfb25a1c22eee76efdf9154da" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -150,53 +157,40 @@ dependencies = [ "zeroize", ] -[[package]] -name = "aws-http" -version = "0.57.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24067106d09620cf02d088166cdaedeaca7146d4d499c41b37accecbea11b246" -dependencies = [ - "aws-smithy-http", - "aws-smithy-runtime-api", - "aws-smithy-types", - "aws-types", - "bytes", - "http", - "http-body", - "pin-project-lite", - "tracing", -] - [[package]] name = "aws-runtime" -version = "0.57.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6ee0152c06d073602236a4e94a8c52a327d310c1ecd596570ce795af8777ff" +checksum = "a10d5c055aa540164d9561a0e2e74ad30f0dcf7393c3a92f6733ddf9c5762468" dependencies = [ "aws-credential-types", - "aws-http", "aws-sigv4", "aws-smithy-async", "aws-smithy-eventstream", "aws-smithy-http", + "aws-smithy-runtime", "aws-smithy-runtime-api", "aws-smithy-types", "aws-types", + "bytes", "fastrand", - "http", + "http 0.2.12", + "http-body 0.4.6", + "once_cell", "percent-encoding", + "pin-project-lite", "tracing", "uuid", ] [[package]] name = "aws-sdk-s3" -version = "0.35.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84022763485483ea17d417f9832d5da198bc36829b59f086c0d35ecd2ce59991" +checksum = "e518950d4ac43508c8bfc2fe4e24b0752d99eab80134461d5e162dcda0214b55" dependencies = [ + "ahash", "aws-credential-types", - "aws-http", "aws-runtime", "aws-sigv4", "aws-smithy-async", @@ -210,37 +204,44 @@ dependencies = [ "aws-smithy-xml", "aws-types", "bytes", - "http", - "http-body", + "fastrand", + "hex", + "hmac", + "http 0.2.12", + "http-body 0.4.6", + "lru", "once_cell", "percent-encoding", - "regex", + "regex-lite", + "sha2", "tracing", "url", ] [[package]] name = "aws-sigv4" -version = "0.57.2" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f81a6abc4daab06b53cabf27c54189928893283093e37164ca53aa47488a5b" +checksum = "cc8db6904450bafe7473c6ca9123f88cc11089e41a025408f992db4e22d3be68" dependencies = [ "aws-credential-types", "aws-smithy-eventstream", "aws-smithy-http", "aws-smithy-runtime-api", + "aws-smithy-types", "bytes", + "crypto-bigint 0.5.5", "form_urlencoded", "hex", "hmac", - "http", - "num-bigint", + "http 0.2.12", + "http 1.1.0", "once_cell", "p256", "percent-encoding", - "regex", "ring 0.17.8", "sha2", + "subtle", "time", "tracing", "zeroize", @@ -248,9 +249,9 @@ dependencies = [ [[package]] name = "aws-smithy-async" -version = "0.57.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe53fccd3b10414b9cae63767a15a2789b34e6c6727b6e32b33e8c7998a3e80" +checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" dependencies = [ "futures-util", "pin-project-lite", @@ -259,9 +260,9 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.57.2" +version = "0.60.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb5701fbfb40600cc0fa547f318552dfd4e632b2099bd75d95fb0faae70675d" +checksum = "598b1689d001c4d4dc3cb386adb07d37786783aee3ac4b324bcadac116bf3d23" dependencies = [ "aws-smithy-http", "aws-smithy-types", @@ -269,8 +270,8 @@ dependencies = [ "crc32c", "crc32fast", "hex", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "md-5", "pin-project-lite", "sha1", @@ -280,9 +281,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.57.2" +version = "0.60.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b33fa99f928a5815b94ee07e1377901bcf51aa749034a2c802dc38f9dcfacf5" +checksum = "cef7d0a272725f87e51ba2bf89f8c21e4df61b9e49ae1ac367a6d69916ef7c90" dependencies = [ "aws-smithy-types", "bytes", @@ -291,9 +292,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.57.2" +version = "0.60.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7972373213d1d6e619c0edc9dda2d6634154e4ed75c5e0b2bf065cd5ec9f0d1" +checksum = "5c8bc3e8fdc6b8d07d976e301c02fe553f72a39b7a9fea820e023268467d7ab6" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", @@ -301,8 +302,8 @@ dependencies = [ "bytes", "bytes-utils", "futures-core", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "once_cell", "percent-encoding", "pin-project-lite", @@ -312,18 +313,18 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.57.2" +version = "0.60.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d64d5af16dd585de9ff6c606423c1aaad47c6baa38de41c2beb32ef21c6645" +checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" dependencies = [ "aws-smithy-types", ] [[package]] name = "aws-smithy-runtime" -version = "0.57.2" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "839b363adf3b2bdab2742a1f540fec23039ea8bc9ec0f9f61df48470cfe5527b" +checksum = "d1ce695746394772e7000b39fe073095db6d45a862d0767dd5ad0ac0d7f8eb87" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -331,8 +332,11 @@ dependencies = [ "aws-smithy-types", "bytes", "fastrand", - "http", - "http-body", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "http-body 1.0.1", + "httparse", "hyper", "hyper-rustls", "once_cell", @@ -345,31 +349,36 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "0.57.2" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24ecc446e62c3924539e7c18dec8038dba4fdf8718d5c2de62f9d2fecca8ba9" +checksum = "e086682a53d3aa241192aa110fa8dfce98f2f5ac2ead0de84d41582c7e8fdb96" dependencies = [ "aws-smithy-async", "aws-smithy-types", "bytes", - "http", + "http 0.2.12", + "http 1.1.0", "pin-project-lite", "tokio", "tracing", + "zeroize", ] [[package]] name = "aws-smithy-types" -version = "0.57.2" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051de910296522a21178a2ea402ea59027eef4b63f1cef04a0be2bb5e25dea03" +checksum = "03701449087215b5369c7ea17fef0dd5d24cb93439ec5af0c7615f58c3f22605" dependencies = [ "base64-simd", "bytes", "bytes-utils", "futures-core", - "http", - "http-body", + "http 0.2.12", + "http 1.1.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", "itoa", "num-integer", "pin-project-lite", @@ -383,24 +392,23 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.57.2" +version = "0.60.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb1e3ac22c652662096c8e37a6f9af80c6f3520cab5610b2fe76c725bce18eac" +checksum = "ab0b0166827aa700d3dc519f72f8b3a91c35d0b8d042dc5d643a91e6f80648fc" dependencies = [ "xmlparser", ] [[package]] name = "aws-types" -version = "0.57.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048bbf1c24cdf4eb1efcdc243388a93a90ebf63979e25fc1c7b8cbd9cb6beb38" +checksum = "5221b91b3e441e6675310829fd8984801b772cb1546ef6c0e54dec9f1ac13fef" dependencies = [ "aws-credential-types", "aws-smithy-async", "aws-smithy-runtime-api", "aws-smithy-types", - "http", "rustc_version", "tracing", ] @@ -417,8 +425,8 @@ dependencies = [ "bytes", "futures-util", "headers", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "hyper", "itoa", "matchit", @@ -447,8 +455,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -464,8 +472,8 @@ dependencies = [ "arc-swap", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "hyper", "pin-project-lite", "rustls 0.20.9", @@ -487,7 +495,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -646,35 +654,33 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.2.7" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", - "bitflags 1.3.2", - "clap_lex 0.4.1", + "clap_lex 0.7.2", "strsim", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.77", @@ -691,9 +697,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "colorchoice" @@ -846,6 +852,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -913,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", - "crypto-bigint", + "crypto-bigint 0.4.9", "der", "digest", "ff", @@ -1139,7 +1155,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap 2.5.0", "slab", "tokio", @@ -1162,15 +1178,16 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] [[package]] name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "headers" @@ -1181,7 +1198,7 @@ dependencies = [ "base64 0.21.7", "bytes", "headers-core", - "http", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -1193,7 +1210,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http", + "http 0.2.12", ] [[package]] @@ -1202,6 +1219,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1217,12 +1240,6 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -1249,6 +1266,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1256,7 +1284,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -1289,8 +1340,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1309,7 +1360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", + "http 0.2.12", "hyper", "log", "rustls 0.21.12", @@ -1371,15 +1422,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" [[package]] -name = "is-terminal" -version = "0.4.13" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -1439,6 +1485,15 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "maligned" version = "0.2.1" @@ -1560,16 +1615,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - [[package]] name = "num-complex" version = "0.4.6" @@ -1773,7 +1818,7 @@ dependencies = [ "libc", "redox_syscall 0.5.4", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -2043,7 +2088,7 @@ dependencies = [ [[package]] name = "reductionist" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-trait", "aws-credential-types", @@ -2054,12 +2099,12 @@ dependencies = [ "aws-types", "axum", "axum-server", - "clap 4.2.7", + "clap 4.5.17", "criterion", "expanduser", "flate2", - "hashbrown 0.12.3", - "http", + "hashbrown 0.14.5", + "http 1.1.0", "hyper", "lazy_static", "maligned", @@ -2125,6 +2170,12 @@ dependencies = [ "regex-syntax 0.8.4", ] +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2143,7 +2194,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac", "zeroize", ] @@ -2536,9 +2587,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum_macros" @@ -2546,7 +2597,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -2806,8 +2857,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "mime", "pin-project-lite", @@ -3189,22 +3240,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3213,22 +3255,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -3237,46 +3264,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -3289,48 +3298,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" diff --git a/Cargo.toml b/Cargo.toml index f132a48..9e2cc2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] name = "reductionist" -version = "0.9.0" +version = "0.10.0" edition = "2021" # Due to AWS SDK. -rust-version = "1.70.0" +rust-version = "1.78.0" license = "Apache-2.0" description = "S3 Active Storage server" homepage = "https://crates.io/crates/reductionist" @@ -26,21 +26,21 @@ maintenance = { status = "actively-developed" } [dependencies] async-trait = "0.1" -aws-credential-types = { version = "0.57.1", features = ["hardcoded-credentials"] } -aws-sdk-s3 = "0.35" -aws-smithy-http = "0.57.1" -aws-smithy-runtime-api = "0.57.1" -aws-smithy-types = "0.57.1" -aws-types = "0.57.1" +aws-credential-types = { version = "1.2", features = ["hardcoded-credentials"] } +aws-sdk-s3 = "1.49" +aws-smithy-http = "0.60" +aws-smithy-runtime-api = "1.7" +aws-smithy-types = "1.2" +aws-types = "1.3" axum = { version = "0.6", features = ["headers"] } axum-server = { version = "0.4.7", features = ["tls-rustls"] } -clap = { version = "~4.2", features = ["derive", "env"] } +clap = { version = "~4.5", features = ["derive", "env"] } expanduser = "1.2.2" flate2 = "1.0" -hashbrown = "0.12" -http = "0.2" +hashbrown = "0.14" +http = "1.1" hyper = { version = "0.14", features = ["full"] } -lazy_static = "1.4" +lazy_static = "1.5" maligned = "0.2.1" mime = "0.3" ndarray = "0.15" diff --git a/Dockerfile b/Dockerfile index 1411ef5..a8c4ade 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ ARG PROFILE=release # Stage 1: builder -FROM rust:1.70 as builder +FROM rust:1.78 as builder ARG PROFILE WORKDIR /build COPY . . @@ -16,7 +16,7 @@ COPY . . RUN cargo install --path . --profile $PROFILE --locked # Stage 2: final image -FROM debian:bullseye-slim +FROM debian:bookworm-slim # AWS SDK requires CA certificates to be present. RUN apt update \ && apt install -y --no-install-recommends ca-certificates \ diff --git a/benches/operations.rs b/benches/operations.rs index ba27941..da4f2fa 100644 --- a/benches/operations.rs +++ b/benches/operations.rs @@ -56,7 +56,7 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter(|| { let mut request_data = get_test_request_data(); request_data.dtype = DType::Int64; - request_data.missing = missing.clone(); + request_data.missing.clone_from(&missing); execute(&request_data, black_box(data.clone())).unwrap(); }) }); diff --git a/docs/contributing.md b/docs/contributing.md index 42d864a..a93215d 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -89,7 +89,7 @@ Building locally may also be preferable during development to take advantage of #### Prerequisites This project is written in Rust, and as such requires a Rust toolchain to be installed in order to build it. -The Minimum Supported Rust Version (MSRV) is 1.70.0, due to a dependency on the [AWS SDK](https://github.com/awslabs/aws-sdk-rust). +The Minimum Supported Rust Version (MSRV) is 1.78.0, due to a dependency on the [AWS SDK](https://github.com/awslabs/aws-sdk-rust). It may be necessary to use [rustup](https://rustup.rs/) rather than the OS provided Rust toolchain to meet this requirement. See the [Rust book](https://doc.rust-lang.org/book/ch01-01-installation.html) for toolchain installation. @@ -231,3 +231,26 @@ In order to make builds reproducible, Cargo maintains a `Cargo.lock` file that c This even allows for multiple versions of a package to be used by a single Rust application, although this can lead to incompatibilities at runtime and should be avoided if possible. To update the versions in the `Cargo.lock` file, run `cargo update`, then inspect and commit the changes. + +### Updating Minimum Supported Rust Version (MSRV) + +Rust moves quickly, and it's sensible to keep up with the latest toolchain. +With support for multiple installed versions of Rust and the separation provided by containers there is little reason to support old versions of Rust. +The AWS SDK for Rust is particularly aggressive in updating its MSRV, and this often drives the MSRV of Reductionist. +Updating the Reductionist MSRV requires making changes in a few places. + +1. `rust-version` in `Cargo.toml` +1. `FROM rust:` in `Dockerfile` +1. `toolchain` in `.github/workflows/publish.yml` +1. Prerequisites section in `docs/contributing.md` + +Updating the MSRV typically requires a few updates to the code to handle changes in the standard library, Clippy rules, etc. + +### Create a release + +To update the version of Reductionist, set `[package] version` in `Cargo.toml`. +Create a pull request, approve and merge it. +When ready to release, [draft a new release](https://github.com/stackhpc/reductionist-rs/releases/new) in GitHub, creating a new tag matching Reductionist's version, and auto-generating release notes. + +After the release is published, the [publish.yml](https://github.com/stackhpc/reductionist-rs/blob/main/.github/workflows/publish.yml) workflow will be triggered. +This workflow publishes the crate to crates.io, and builds then publishes a container image on GHCR. diff --git a/src/array.rs b/src/array.rs index 76e804b..8fcc964 100644 --- a/src/array.rs +++ b/src/array.rs @@ -46,7 +46,7 @@ pub fn get_shape( } } -/// Returns an [ndarray::ArrayView](ndarray::ArrayView) corresponding to the data in the +/// Returns an [ndarray::ArrayView] corresponding to the data in the /// request. /// /// The array view borrows the data, so no copying takes place. @@ -62,7 +62,7 @@ fn build_array_from_shape( ArrayView::::from_shape(shape, data).map_err(ActiveStorageError::ShapeInvalid) } -/// Returns a mutable [ndarray::ArrayViewMut](ndarray::ArrayViewMut) corresponding to the data in +/// Returns a mutable [ndarray::ArrayViewMut] corresponding to the data in /// the request. /// /// The array view borrows the data, so no copying takes place. @@ -176,7 +176,7 @@ pub fn reverse_array_byte_order( } } -/// Build an [ndarray::ArrayView](ndarray::ArrayView) object corresponding to the request and data bytes. +/// Build an [ndarray::ArrayView] object corresponding to the request and data bytes. /// /// The resulting array will contain a reference to `data`. /// diff --git a/src/compression.rs b/src/compression.rs index 13ebafc..7e3c310 100644 --- a/src/compression.rs +++ b/src/compression.rs @@ -13,7 +13,7 @@ use zune_inflate::{DeflateDecoder, DeflateOptions}; /// # Arguments /// /// * `compression`: Compression algorithm -/// * `data`: Compressed data [Bytes](axum::body::Bytes) +/// * `data`: Compressed data [Bytes] pub fn decompress( compression: models::Compression, data: &Bytes, diff --git a/src/error.rs b/src/error.rs index 82a0e62..4f8d7a8 100644 --- a/src/error.rs +++ b/src/error.rs @@ -66,6 +66,10 @@ pub enum ActiveStorageError { #[error("error receiving object from S3 storage")] S3ByteStream(#[from] ByteStreamError), + /// Missing Content-Length header in S3 response. + #[error("S3 response missing Content-Length header")] + S3ContentLengthMissing, + /// Error while retrieving an object from S3 #[error("error retrieving object from S3 storage")] S3GetObject(#[from] SdkError), @@ -213,6 +217,7 @@ impl From for ErrorResponse { | ActiveStorageError::RequestDataJsonRejection(_) | ActiveStorageError::RequestDataValidationSingle(_) | ActiveStorageError::RequestDataValidation(_) + | ActiveStorageError::S3ContentLengthMissing | ActiveStorageError::ShapeInvalid(_) => Self::bad_request(&error), // Not found @@ -244,7 +249,7 @@ impl From for ErrorResponse { // Quite a lot of error cases end up as unhandled. Attempt to determine // the error from the code. - GetObjectError::Unhandled(_) => { + _ => { match get_obj_error.code() { // Bad request Some("NoSuchBucket") => Self::bad_request(&error), @@ -258,9 +263,6 @@ impl From for ErrorResponse { _ => Self::internal_server_error(&error), } } - - // The enum is marked as non-exhaustive - _ => Self::internal_server_error(&error), } } @@ -311,9 +313,9 @@ mod tests { use super::*; use aws_sdk_s3::types::error::NoSuchKey; - use aws_smithy_runtime_api::client::orchestrator::HttpResponse as SmithyResponse; - use aws_smithy_types::Error as SmithyError; - use http::response::Response as HttpResponse; + use aws_smithy_runtime_api::http::Response as SmithyResponse; + use aws_smithy_runtime_api::http::StatusCode as SmithyStatusCode; + use aws_smithy_types::error::ErrorMetadata as SmithyError; use hyper::HeaderMap; // Jump through the hoops to get the body as a string. @@ -423,6 +425,13 @@ mod tests { test_active_storage_error(error, StatusCode::BAD_REQUEST, message, caused_by).await; } + #[tokio::test] + async fn s3_content_length_missing() { + let error = ActiveStorageError::S3ContentLengthMissing; + let message = "S3 response missing Content-Length header"; + test_active_storage_error(error, StatusCode::BAD_REQUEST, message, None).await; + } + // Helper function for S3 GetObjectError errors async fn test_s3_get_object_error( sdk_error: SdkError, @@ -436,7 +445,8 @@ mod tests { fn get_smithy_response() -> SmithyResponse { let sdk_body = "body"; - HttpResponse::new(sdk_body.into()) + let status: SmithyStatusCode = 400.try_into().unwrap(); + SmithyResponse::new(status, sdk_body.into()) } #[tokio::test] @@ -460,7 +470,7 @@ mod tests { let sdk_error = SdkError::service_error(get_object_error, get_smithy_response()); let caused_by = Some(vec![ "service error", - "unhandled error", + "unhandled error (InvalidAccessKeyId)", "Error { code: \"InvalidAccessKeyId\", message: \"fake smithy error\" }", ]); test_s3_get_object_error(sdk_error, StatusCode::UNAUTHORIZED, caused_by).await; @@ -477,7 +487,7 @@ mod tests { let sdk_error = SdkError::service_error(get_object_error, get_smithy_response()); let caused_by = Some(vec![ "service error", - "unhandled error", + "unhandled error (NoSuchBucket)", "Error { code: \"NoSuchBucket\", message: \"fake smithy error\" }", ]); test_s3_get_object_error(sdk_error, StatusCode::BAD_REQUEST, caused_by).await; @@ -494,7 +504,7 @@ mod tests { let sdk_error = SdkError::service_error(get_object_error, get_smithy_response()); let caused_by = Some(vec![ "service error", - "unhandled error", + "unhandled error (SignatureDoesNotMatch)", "Error { code: \"SignatureDoesNotMatch\", message: \"fake smithy error\" }", ]); test_s3_get_object_error(sdk_error, StatusCode::UNAUTHORIZED, caused_by).await; @@ -511,7 +521,7 @@ mod tests { let sdk_error = SdkError::service_error(get_object_error, get_smithy_response()); let caused_by = Some(vec![ "service error", - "unhandled error", + "unhandled error (AccessDenied)", "Error { code: \"AccessDenied\", message: \"fake smithy error\" }", ]); test_s3_get_object_error(sdk_error, StatusCode::UNAUTHORIZED, caused_by).await; diff --git a/src/filters.rs b/src/filters.rs index a10585c..1608ea7 100644 --- a/src/filters.rs +++ b/src/filters.rs @@ -12,7 +12,7 @@ use axum::body::Bytes; /// # Arguments /// /// * `filter`: Filter algorithm -/// * `data`: Filtered data [Bytes](axum::body::Bytes) +/// * `data`: Filtered data [Bytes] pub fn decode(filter: &models::Filter, data: &Bytes) -> Result { match filter { models::Filter::Shuffle { element_size } => Ok(shuffle::deshuffle(data, *element_size)), diff --git a/src/models.rs b/src/models.rs index c2ec0d3..2c1472c 100644 --- a/src/models.rs +++ b/src/models.rs @@ -169,10 +169,7 @@ fn validate_slice(slice: &Slice) -> Result<(), ValidationError> { } /// Validate that a shape and selection are consistent -fn validate_shape_selection( - shape: &Vec, - selection: &Vec, -) -> Result<(), ValidationError> { +fn validate_shape_selection(shape: &[usize], selection: &[Slice]) -> Result<(), ValidationError> { if shape.len() != selection.len() { let mut error = ValidationError::new("Shape and selection must have the same length"); error.add_param("shape".into(), &shape.len()); diff --git a/src/operation.rs b/src/operation.rs index c45c148..220f4cf 100644 --- a/src/operation.rs +++ b/src/operation.rs @@ -51,7 +51,7 @@ impl Element for T where pub trait Operation { /// Execute the operation. /// - /// Returns a [models::Response](crate::models::Response) object with response data. + /// Returns a [models::Response] object with response data. /// /// # Arguments /// diff --git a/src/s3_client.rs b/src/s3_client.rs index d1352cc..9fd715d 100644 --- a/src/s3_client.rs +++ b/src/s3_client.rs @@ -5,6 +5,7 @@ use crate::error::ActiveStorageError; use crate::resource_manager::ResourceManager; use aws_credential_types::Credentials; +use aws_sdk_s3::config::BehaviorVersion; use aws_sdk_s3::Client; use aws_types::region::Region; use axum::body::Bytes; @@ -102,7 +103,7 @@ impl S3Client { /// * `credentials`: Object storage account credentials pub async fn new(url: &Url, credentials: S3Credentials) -> Self { let region = Region::new("us-east-1"); - let builder = aws_sdk_s3::Config::builder(); + let builder = aws_sdk_s3::Config::builder().behavior_version(BehaviorVersion::latest()); let builder = match credentials { S3Credentials::AccessKey { access_key, @@ -148,12 +149,15 @@ impl S3Client { .send() .instrument(tracing::Span::current()) .await?; - let content_length = response.content_length(); + // Fail if the content length header is missing. + let content_length: usize = response + .content_length() + .ok_or(ActiveStorageError::S3ContentLengthMissing)? + .try_into()?; // FIXME: how to account for compressed data? if mem_permits.is_none() { - let memory = content_length.try_into()?; - *mem_permits = resource_manager.memory(memory).await?; + *mem_permits = resource_manager.memory(content_length).await?; }; // The data returned by the S3 client does not have any alignment guarantees. In order to // reinterpret the data as an array of numbers with a higher alignment than 1, we need to @@ -161,7 +165,7 @@ impl S3Client { // For now we're hard-coding an alignment of 8 bytes, although this should depend on the // data type, and potentially whether there are any SIMD requirements. // Create an 8-byte aligned Vec. - let mut buf = maligned::align_first::(content_length as usize); + let mut buf = maligned::align_first::(content_length); // Iterate over the streaming response, copying data into the aligned Vec. while let Some(bytes) = response diff --git a/src/types/dvalue.rs b/src/types/dvalue.rs index 6ae1689..8eeb156 100644 --- a/src/types/dvalue.rs +++ b/src/types/dvalue.rs @@ -30,11 +30,11 @@ fn as_f64(value: &DValue) -> Result { .ok_or(ActiveStorageError::IncompatibleMissing(value.clone())) } -/// Attempt to convert from a [DValue](crate::types::DValue) to specific numeric type. +/// Attempt to convert from a [DValue] to specific numeric type. // This trait exists because we can't implement TryFrom for numeric types because the trait // and type are in external crates. pub trait TryFromDValue: Sized { - /// Try to convert from a [DValue](crate::types::DValue) to a numeric type. + /// Try to convert from a [DValue] to a numeric type. fn try_from_dvalue(value: DValue) -> Result; } diff --git a/src/types/missing.rs b/src/types/missing.rs index e243b14..e877c68 100644 --- a/src/types/missing.rs +++ b/src/types/missing.rs @@ -21,8 +21,8 @@ use crate::types::DValue; /// /// This enum can represent all known descriptions of missing data used in NetCDF4 files. /// It is generic over the type of missing data values. We use this in two ways: -/// 1. T = [DValue](crate::types::DValue), used in the API to represent values of any supported -/// [DType](crate::models::DType). +/// 1. T = [DValue], used in the API to represent values of any supported +/// [DType]. /// 2. T = a primitive numeric type (i32, u64, f32, etc.), used in numeric operations when we know /// the DType of the values. #[derive(Clone, Debug, Deserialize, PartialEq)] @@ -42,7 +42,7 @@ pub enum Missing { impl Missing { /// Validate a [`Missing`](crate::types::Missing) object for a given - /// [DType](crate::models::DType). + /// [DType]. pub fn validate(&self, dtype: DType) -> Result<(), ValidationError> { match dtype { DType::Int32 => Missing::::validate_dvalue(self),