From 281fcb7ef411f2708d5c24c9989fd2e4e1af9540 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Fri, 17 Sep 2021 19:58:45 +0800 Subject: [PATCH 1/6] upgrade lambda_runtime crate dependencies & add async handler fn support --- .gitignore | 1 + Cargo.lock | 1034 ------------------------------------------ Cargo.toml | 39 +- package/CHANGELOG.md | 8 + src/body.rs | 174 +++---- src/error.rs | 39 +- src/lib.rs | 265 ++++++++--- src/request.rs | 173 ++++--- src/response.rs | 126 ++--- src/strmap.rs | 114 ++--- 10 files changed, 555 insertions(+), 1418 deletions(-) delete mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index c732e36..12ec4c1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ node_modules/ .vercel/ fixtures/**/vercel.json +cargo.lock diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 3896ffd..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,1034 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "backtrace" -version = "0.3.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" -dependencies = [ - "backtrace-sys", - "cfg-if", - "libc", - "rustc-demangle", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "byteorder" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "either", - "iovec", -] - -[[package]] -name = "cc" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "chrono" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8493056968583b0193c1bb04d6f7684586f3726992d6c573261941a895dbd68" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils 0.7.0", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils 0.7.0", - "lazy_static", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" -dependencies = [ - "crossbeam-utils 0.6.6", -] - -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "either" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" - -[[package]] -name = "failure" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" -dependencies = [ - "proc-macro2 1.0.6", - "quote 1.0.2", - "syn 1.0.8", - "synstructure 0.12.3", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" - -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -dependencies = [ - "futures", - "num_cpus", -] - -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -dependencies = [ - "byteorder", - "bytes", - "fnv", - "futures", - "http", - "indexmap", - "log", - "slab", - "string", - "tokio-io", -] - -[[package]] -name = "hermit-abi" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" -dependencies = [ - "libc", -] - -[[package]] -name = "http" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7e06e336150b178206af098a055e3621e8336027e2b4d126bda0bc64824baaf" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes", - "futures", - "http", - "tokio-buf", -] - -[[package]] -name = "httparse" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" - -[[package]] -name = "hyper" -version = "0.12.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" -dependencies = [ - "bytes", - "futures", - "futures-cpupool", - "h2", - "http", - "http-body", - "httparse", - "iovec", - "itoa", - "log", - "net2", - "rustc_version", - "time", - "tokio", - "tokio-buf", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "want", -] - -[[package]] -name = "indexmap" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" -dependencies = [ - "autocfg", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "itoa" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "lambda_runtime" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "077b8819fe6998266342efdc5154192551143f390ab758007cc7421992e61b07" -dependencies = [ - "failure", - "lambda_runtime_core", - "log", - "serde", - "serde_derive", - "serde_json", - "tokio", -] - -[[package]] -name = "lambda_runtime_client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e64758b587f1d07b6ca4814a3bc0f3db48c89cc3c895db43a23c690855b370" -dependencies = [ - "failure", - "http", - "hyper", - "lambda_runtime_errors", - "log", - "serde", - "serde_derive", - "serde_json", - "tokio", -] - -[[package]] -name = "lambda_runtime_core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1cb59e060c1068cfa386b58c202a4381c509ace85a1eadab505164f0563ca5" -dependencies = [ - "backtrace", - "chrono", - "failure", - "hyper", - "lambda_runtime_client", - "lambda_runtime_errors", - "log", - "rustc_version", - "tokio", -] - -[[package]] -name = "lambda_runtime_errors" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b63ea3688df164aaa5643c5f3291cc481366d624729deb3c4dc85ee65ac20a" -dependencies = [ - "failure", - "lambda_runtime_errors_derive", - "log", - "serde_json", -] - -[[package]] -name = "lambda_runtime_errors_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38fa619ec6f1ee2371a109683d251035c83f01b8ffc10f4aa46de821836a7baf" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", - "synstructure 0.10.2", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" - -[[package]] -name = "lock_api" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memoffset" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" -dependencies = [ - "rustc_version", -] - -[[package]] -name = "mio" -version = "0.6.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" -dependencies = [ - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-uds" -version = "0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "net2" -version = "0.2.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -dependencies = [ - "cfg-if", - "libc", - "winapi 0.3.8", -] - -[[package]] -name = "num-integer" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155394f924cdddf08149da25bfb932d226b4a593ca7468b08191ff6335941af5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api", - "parking_lot_core", - "rustc_version", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" -dependencies = [ - "cfg-if", - "cloudabi", - "libc", - "redox_syscall", - "rustc_version", - "smallvec", - "winapi 0.3.8", -] - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" -dependencies = [ - "unicode-xid 0.2.0", -] - -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - -[[package]] -name = "quote" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" -dependencies = [ - "proc-macro2 1.0.6", -] - -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" - -[[package]] -name = "rustc-demangle" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "ryu" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" - -[[package]] -name = "scopeguard" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" - -[[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-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "serde" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0" - -[[package]] -name = "serde_derive" -version = "1.0.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8" -dependencies = [ - "proc-macro2 1.0.6", - "quote 1.0.2", - "syn 1.0.8", -] - -[[package]] -name = "serde_json" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" - -[[package]] -name = "smallvec" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "string" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" -dependencies = [ - "bytes", -] - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92" -dependencies = [ - "proc-macro2 1.0.6", - "quote 1.0.2", - "unicode-xid 0.2.0", -] - -[[package]] -name = "synstructure" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", - "unicode-xid 0.1.0", -] - -[[package]] -name = "synstructure" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" -dependencies = [ - "proc-macro2 1.0.6", - "quote 1.0.2", - "syn 1.0.8", - "unicode-xid 0.2.0", -] - -[[package]] -name = "time" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -dependencies = [ - "libc", - "redox_syscall", - "winapi 0.3.8", -] - -[[package]] -name = "tokio" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -dependencies = [ - "bytes", - "futures", - "mio", - "num_cpus", - "tokio-codec", - "tokio-current-thread", - "tokio-executor", - "tokio-fs", - "tokio-io", - "tokio-reactor", - "tokio-sync", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "tokio-udp", - "tokio-uds", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes", - "either", - "futures", -] - -[[package]] -name = "tokio-codec" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -dependencies = [ - "bytes", - "futures", - "tokio-io", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" -dependencies = [ - "futures", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" -dependencies = [ - "crossbeam-utils 0.6.6", - "futures", -] - -[[package]] -name = "tokio-fs" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" -dependencies = [ - "futures", - "tokio-io", - "tokio-threadpool", -] - -[[package]] -name = "tokio-io" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" -dependencies = [ - "bytes", - "futures", - "log", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56391be9805bc80163151c0b9e5164ee64f4b0200962c346fea12773158f22d" -dependencies = [ - "crossbeam-utils 0.6.6", - "futures", - "lazy_static", - "log", - "mio", - "num_cpus", - "parking_lot", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - -[[package]] -name = "tokio-sync" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06554cce1ae4a50f42fba8023918afa931413aded705b560e29600ccf7c6d76" -dependencies = [ - "fnv", - "futures", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -dependencies = [ - "bytes", - "futures", - "iovec", - "mio", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd2c6a3885302581f4401c82af70d792bb9df1700e7437b0aeb4ada94d5388c" -dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils 0.6.6", - "futures", - "lazy_static", - "log", - "num_cpus", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-timer" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" -dependencies = [ - "crossbeam-utils 0.6.6", - "futures", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-udp" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02298505547f73e60f568359ef0d016d5acd6e830ab9bc7c4a5b3403440121b" -dependencies = [ - "bytes", - "futures", - "log", - "mio", - "tokio-codec", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-uds" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -dependencies = [ - "bytes", - "futures", - "iovec", - "libc", - "log", - "mio", - "mio-uds", - "tokio-codec", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "try-lock" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" - -[[package]] -name = "vercel_lambda" -version = "0.2.0" -dependencies = [ - "base64", - "http", - "lambda_runtime", - "log", - "serde", - "serde_derive", - "serde_json", - "tokio", -] - -[[package]] -name = "want" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -dependencies = [ - "futures", - "log", - "try-lock", -] - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - -[[package]] -name = "winapi" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/Cargo.toml b/Cargo.toml index 36aebd9..34e7f2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,25 +1,38 @@ [package] name = "vercel_lambda" -version = "0.2.0" +version = "0.3.0" + authors = ["Vercel "] -edition = "2018" description = "Rust runtime for Vercel Functions." +documentation = "https://docs.rs/vercel_lambda" +homepage = "https://github.com/vercel-community/rust" keywords = ["Vercel", "Rust", "Serverless", "Functions"] license = "MIT" -homepage = "https://github.com/vercel-community/rust" repository = "https://github.com/vercel-community/rust" -documentation = "https://docs.rs/vercel_lambda" + +edition = "2018" +resolver = "2" + include = [ "src/*.rs", - "Cargo.toml" + "Cargo.toml", ] +[features] +default = ["runtime"] + +runtime = ["tokio"] + [dependencies] -serde = "^1" -serde_json = "^1" -serde_derive = "^1" -http = "0.1" -tokio = "^0.1" -base64 = "0.10" -log = "^0.4" -lambda_runtime = "0.2.0" +base64 = "0.13" +http = "0.2" +lambda_runtime = "0.4" +log = "0.4" +serde = "1" +serde_derive = "1" +serde_json = "1" +tokio = {version = "1.11", optional = true} + +[dev-dependencies] +anyhow = "1" +tokio = "1.11" diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index 3a27077..17076f0 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -2,6 +2,14 @@ ## Unreleased +## 0.3.0 + +- Add async handler fn support +- Make tokio an optional dependency behind feature `runtime` (default on) +- Upgrade tokio to 1.11 +- Upgrade http to 0.2 +- Upgrade lambda_runtime to 0.4 + ## 0.2.0 - Renamed to vercel_lambda diff --git a/src/body.rs b/src/body.rs index ac849b2..b4519f9 100644 --- a/src/body.rs +++ b/src/body.rs @@ -56,139 +56,139 @@ use serde::ser::{Error as SerError, Serialize, Serializer}; /// ``` #[derive(Debug, PartialEq)] pub enum Body { - /// An empty body - Empty, - /// A body containing string data - Text(String), - /// A body containing binary data - Binary(Vec), + /// An empty body + Empty, + /// A body containing string data + Text(String), + /// A body containing binary data + Binary(Vec), } impl Default for Body { - fn default() -> Self { - Body::Empty - } + fn default() -> Self { + Body::Empty + } } impl From<()> for Body { - fn from(_: ()) -> Self { - Body::Empty - } + fn from(_: ()) -> Self { + Body::Empty + } } impl From for () { - fn from(_: Body) -> Self {} + fn from(_: Body) -> Self {} } impl<'a> From<&'a str> for Body { - fn from(s: &'a str) -> Self { - Body::Text(s.into()) - } + fn from(s: &'a str) -> Self { + Body::Text(s.into()) + } } impl From for Body { - fn from(b: String) -> Self { - Body::Text(b) - } + fn from(b: String) -> Self { + Body::Text(b) + } } impl From for String { - fn from(b: Body) -> String { - match b { - Body::Empty => String::from(""), - Body::Text(t) => t, - Body::Binary(b) => str::from_utf8(&b).unwrap().to_owned(), - } - } + fn from(b: Body) -> String { + match b { + Body::Empty => String::from(""), + Body::Text(t) => t, + Body::Binary(b) => str::from_utf8(&b).unwrap().to_owned(), + } + } } impl From> for Body { - #[inline] - fn from(cow: Cow<'static, str>) -> Body { - match cow { - Cow::Borrowed(b) => Body::from(b.to_owned()), - Cow::Owned(o) => Body::from(o), - } - } + #[inline] + fn from(cow: Cow<'static, str>) -> Body { + match cow { + Cow::Borrowed(b) => Body::from(b.to_owned()), + Cow::Owned(o) => Body::from(o), + } + } } impl From for Cow<'static, str> { - #[inline] - fn from(b: Body) -> Cow<'static, str> { - Cow::Owned(String::from(b)) - } + #[inline] + fn from(b: Body) -> Cow<'static, str> { + Cow::Owned(String::from(b)) + } } impl From> for Body { - #[inline] - fn from(cow: Cow<'static, [u8]>) -> Body { - match cow { - Cow::Borrowed(b) => Body::from(b), - Cow::Owned(o) => Body::from(o), - } - } + #[inline] + fn from(cow: Cow<'static, [u8]>) -> Body { + match cow { + Cow::Borrowed(b) => Body::from(b), + Cow::Owned(o) => Body::from(o), + } + } } impl From for Cow<'static, [u8]> { - #[inline] - fn from(b: Body) -> Self { - Cow::Owned(b.as_ref().to_owned()) - } + #[inline] + fn from(b: Body) -> Self { + Cow::Owned(b.as_ref().to_owned()) + } } impl From> for Body { - fn from(b: Vec) -> Self { - Body::Binary(b) - } + fn from(b: Vec) -> Self { + Body::Binary(b) + } } impl From for Vec { - fn from(b: Body) -> Self { - match b { - Body::Empty => "".as_bytes().to_owned(), - Body::Text(t) => t.into_bytes(), - Body::Binary(b) => b, - } - } + fn from(b: Body) -> Self { + match b { + Body::Empty => "".as_bytes().to_owned(), + Body::Text(t) => t.into_bytes(), + Body::Binary(b) => b, + } + } } impl<'a> From<&'a [u8]> for Body { - fn from(b: &'a [u8]) -> Self { - Body::Binary(b.to_vec()) - } + fn from(b: &'a [u8]) -> Self { + Body::Binary(b.to_vec()) + } } impl Deref for Body { - type Target = [u8]; + type Target = [u8]; - #[inline] - fn deref(&self) -> &Self::Target { - self.as_ref() - } + #[inline] + fn deref(&self) -> &Self::Target { + self.as_ref() + } } impl AsRef<[u8]> for Body { - #[inline] - fn as_ref(&self) -> &[u8] { - match self { - Body::Empty => &[], - Body::Text(ref bytes) => bytes.as_ref(), - Body::Binary(ref bytes) => bytes.as_ref(), - } - } + #[inline] + fn as_ref(&self) -> &[u8] { + match self { + Body::Empty => &[], + Body::Text(ref bytes) => bytes.as_ref(), + Body::Binary(ref bytes) => bytes.as_ref(), + } + } } impl<'a> Serialize for Body { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self { - Body::Text(data) => serializer - .serialize_str(::std::str::from_utf8(data.as_ref()).map_err(S::Error::custom)?), - Body::Binary(data) => { - serializer.collect_str(&Base64Display::with_config(data, base64::STANDARD)) - } - Body::Empty => serializer.serialize_unit(), - } - } + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Body::Text(data) => serializer + .serialize_str(::std::str::from_utf8(data.as_ref()).map_err(S::Error::custom)?), + Body::Binary(data) => { + serializer.collect_str(&Base64Display::with_config(data, base64::STANDARD)) + } + Body::Empty => serializer.serialize_unit(), + } + } } diff --git a/src/error.rs b/src/error.rs index 83c92a8..07fcade 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,43 +1,34 @@ -use lambda_runtime::error::LambdaErrorExt; use std::{error::Error, fmt}; /// This module implements a custom error currently over the AWS Lambda runtime, /// which can be extended later to support more service providers. #[derive(Debug)] pub struct VercelError { - msg: String, + msg: String, } impl VercelError { - pub fn new(message: &str) -> VercelError { - VercelError { - msg: message.to_owned(), - } - } + pub fn new(message: &str) -> VercelError { + VercelError { + msg: message.to_owned(), + } + } } impl fmt::Display for VercelError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.msg) - } + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.msg) + } } impl Error for VercelError {} impl From for VercelError { - fn from(i: std::num::ParseIntError) -> Self { - VercelError::new(&format!("{}", i)) - } + fn from(i: std::num::ParseIntError) -> Self { + VercelError::new(&format!("{}", i)) + } } impl From for VercelError { - fn from(i: http::Error) -> Self { - VercelError::new(&format!("{}", i)) - } -} - -// the value returned by the error_type function is included as the -// `errorType` in the AWS Lambda response -impl LambdaErrorExt for VercelError { - fn error_type(&self) -> &str { - "VercelError" - } + fn from(i: http::Error) -> Self { + VercelError::new(&format!("{}", i)) + } } diff --git a/src/lib.rs b/src/lib.rs index 7eec63b..d41bd5c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ pub use http::{self, Response}; -use lambda_runtime::{self as lambda, Context}; +use lambda_runtime::{self as lambda, handler_fn, Context}; use log::{self, debug, error}; use serde_json::Error; -use tokio::runtime::Runtime as TokioRuntime; +use std::future::Future; mod body; pub mod error; @@ -12,80 +12,239 @@ mod strmap; pub use crate::{body::Body, response::IntoResponse, strmap::StrMap}; use crate::{ - error::VercelError, - request::{VercelEvent, VercelRequest}, - response::VercelResponse, + error::VercelError, + request::{VercelEvent, VercelRequest}, + response::VercelResponse, }; /// Type alias for `http::Request`s with a fixed `Vercel_lambda::Body` body pub type Request = http::Request; -/// Functions acting as Vercel Lambda handlers must conform to this type. -pub trait Handler { - /// Method to execute the handler function - fn run(&mut self, event: http::Request) -> Result; +/// Creates a new `lambda_runtime::Runtime` and begins polling for Vercel Lambda events +/// +/// # Arguments +/// +/// * `f` function pointer type `fn(http::Request) -> Result` +/// +/// # Panics +/// The function panics if the Lambda environment variables are not set. +#[cfg(feature = "runtime")] +#[inline] +pub fn start( + f: fn(http::Request) -> Result, + runtime: Option, +) where + B: From, + E: Into, + R: IntoResponse, +{ + let runtime = get_runtime(runtime); + runtime.block_on(start_handler_async(f)).unwrap(); } -impl Handler for Function +#[inline] +pub async fn start_handler_async( + f: fn(http::Request) -> Result, +) -> Result<(), Box> where - Function: FnMut(http::Request) -> Result, + B: From, + E: Into, + R: IntoResponse, { - fn run(&mut self, event: http::Request) -> Result { - (*self)(event) - } + let func = |e: VercelEvent, ctx: Context| process_vercel_request(f, e, ctx); + let func = handler_fn(func); + lambda::run(func).await +} + +async fn process_vercel_request( + f: fn(http::Request) -> Result, + e: VercelEvent, + _ctx: Context, +) -> Result +where + B: From, + E: Into, + R: IntoResponse, +{ + let parse_result: Result = serde_json::from_str(&e.body); + match parse_result { + Ok(req) => { + debug!("Deserialized Vercel proxy request successfully"); + let request: Request = req.into(); + let request = request.map(|b| b.into()); + f(request) + .map(|resp| VercelResponse::from(resp.into_response())) + .map_err(|e| e.into()) + } + Err(e) => { + error!("Could not deserialize event body to VercelRequest {}", e); + panic!("Could not deserialize event body to VercelRequest {}", e); + } + } } /// Creates a new `lambda_runtime::Runtime` and begins polling for Vercel Lambda events /// /// # Arguments /// -/// * `f` A type that conforms to the `Handler` interface. +/// * `f` function pointer type `fn(http::Request) -> Future>` /// /// # Panics /// The function panics if the Lambda environment variables are not set. -pub fn start(f: impl Handler, runtime: Option) +#[cfg(feature = "runtime")] +#[inline] +pub fn start_async_handler( + f: fn(http::Request) -> F, + runtime: Option, +) where + F: Future>, + B: From, + E: Into, + R: IntoResponse, +{ + let runtime = get_runtime(runtime); + runtime.block_on(start_async_handler_async(f)).unwrap(); +} + +#[inline] +pub async fn start_async_handler_async( + f: fn(http::Request) -> F, +) -> Result<(), Box> where - B: From, - E: Into, - R: IntoResponse, + F: Future>, + B: From, + E: Into, + R: IntoResponse, { - // handler requires a mutable ref - let mut func = f; - lambda::start( - |e: VercelEvent, _ctx: Context| { - let req_str = e.body; - let parse_result: Result = serde_json::from_str(&req_str); - match parse_result { - Ok(req) => { - debug!("Deserialized Vercel proxy request successfully"); - let request: http::Request = req.into(); - func.run(request.map(|b| b.into())) - .map(|resp| VercelResponse::from(resp.into_response())) - .map_err(|e| e.into()) - } - Err(e) => { - error!("Could not deserialize event body to VercelRequest {}", e); - panic!("Could not deserialize event body to VercelRequest {}", e); - } - } - }, - runtime, - ) + let func = |e: VercelEvent, ctx: Context| process_vercel_request_with_async_handler(f, e, ctx); + let func = handler_fn(func); + lambda::run(func).await +} + +async fn process_vercel_request_with_async_handler( + f: fn(http::Request) -> F, + e: VercelEvent, + _ctx: Context, +) -> Result +where + F: Future>, + B: From, + E: Into, + R: IntoResponse, +{ + let parse_result: Result = serde_json::from_str(&e.body); + match parse_result { + Ok(req) => { + debug!("Deserialized Vercel proxy request successfully"); + let request: Request = req.into(); + let request: http::Request = request.map(|b| b.into()); + let future = f(request); + let r = future.await; + r.map(|resp| VercelResponse::from(resp.into_response())) + .map_err(|e| e.into()) + } + Err(e) => { + error!("Could not deserialize event body to VercelRequest {}", e); + panic!("Could not deserialize event body to VercelRequest {}", e); + } + } +} + +#[cfg(feature = "runtime")] +#[inline] +fn get_runtime(runtime: Option) -> tokio::runtime::Runtime { + match runtime { + Some(rt) => rt, + _ => tokio::runtime::Builder::new_multi_thread() + .build() + .unwrap_or_else(|_| { + tokio::runtime::Builder::new_current_thread() + .build() + .unwrap() + }), + } } /// A macro for starting new handler's poll for Vercel Lambda events +#[cfg(feature = "runtime")] #[macro_export] macro_rules! lambda { - ($handler:expr) => { - $crate::start($handler, None) - }; - ($handler:expr, $runtime:expr) => { - $crate::start($handler, Some($runtime)) - }; - ($handler:ident) => { - $crate::start($handler, None) - }; - ($handler:ident, $runtime:expr) => { - $crate::start($handler, Some($runtime)) - }; + ($handler:expr) => { + $crate::start($handler, None) + }; + ($handler:expr, $runtime:expr) => { + $crate::start($handler, Some($runtime)) + }; + ($handler:ident) => { + $crate::start($handler, None) + }; + ($handler:ident, $runtime:expr) => { + $crate::start($handler, Some($runtime)) + }; +} + +/// A macro for starting new async handler's poll for Vercel Lambda events +#[cfg(feature = "runtime")] +#[macro_export] +macro_rules! lambda_async { + ($handler:expr) => { + $crate::start_async_handler($handler, None) + }; + ($handler:expr, $runtime:expr) => { + $crate::start_async_handler($handler, Some($runtime)) + }; + ($handler:ident) => { + $crate::start_async_handler($handler, None) + }; + ($handler:ident, $runtime:expr) => { + $crate::start_async_handler($handler, Some($runtime)) + }; +} + +#[cfg(test)] +mod test { + use crate::{error::VercelError, *}; + #[test] + fn handler_compile_test() { + fn _my_handler(_request: Request) -> Result { + let response = Response::builder() + .status(200) + .header("Content-Type", "text/plain") + .body("Hello world") + .expect("Internal Server Error"); + Ok(response) + } + + #[cfg(feature = "runtime")] + fn _main() -> Result<(), Box> { + Ok(lambda!(_my_handler)) + } + + #[tokio::main] + async fn _async_main() -> Result<(), Box> { + start_handler_async(_my_handler).await + } + } + + #[test] + fn async_handler_compile_test() { + async fn _my_async_handler(_request: Request) -> Result { + let response = Response::builder() + .status(200) + .header("Content-Type", "text/plain") + .body("Hello world") + .expect("Internal Server Error"); + Ok(response) + } + + #[cfg(feature = "runtime")] + fn _main() -> Result<(), Box> { + Ok(lambda_async!(_my_async_handler)) + } + + #[tokio::main] + async fn _async_main() -> Result<(), Box> { + start_async_handler_async(_my_async_handler).await + } + } } diff --git a/src/request.rs b/src/request.rs index 3cd6b05..5b2ea80 100644 --- a/src/request.rs +++ b/src/request.rs @@ -11,112 +11,111 @@ use crate::body::Body; #[derive(Deserialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub(crate) struct VercelRequest<'a> { - pub(crate) host: Cow<'a, str>, - pub(crate) path: Cow<'a, str>, - #[serde(deserialize_with = "deserialize_method")] - pub(crate) method: Method, - #[serde(deserialize_with = "deserialize_headers")] - pub(crate) headers: HeaderMap, - pub(crate) body: Option>, - pub(crate) encoding: Option, + pub(crate) host: Cow<'a, str>, + pub(crate) path: Cow<'a, str>, + #[serde(deserialize_with = "deserialize_method")] + pub(crate) method: Method, + #[serde(deserialize_with = "deserialize_headers")] + pub(crate) headers: HeaderMap, + pub(crate) body: Option>, + pub(crate) encoding: Option, } #[doc(hidden)] #[derive(Deserialize, Debug, Default)] -pub(crate) struct VercelEvent<'a> { - #[serde(rename = "Action")] - action: Cow<'a, str>, - pub(crate) body: Cow<'a, str>, +pub(crate) struct VercelEvent { + #[serde(rename = "Action")] + action: String, + pub(crate) body: String, } fn deserialize_method<'de, D>(deserializer: D) -> Result where - D: Deserializer<'de>, + D: Deserializer<'de>, { - struct MethodVisitor; + struct MethodVisitor; - impl<'de> Visitor<'de> for MethodVisitor { - type Value = Method; + impl<'de> Visitor<'de> for MethodVisitor { + type Value = Method; - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a Method") - } + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "a Method") + } - fn visit_str(self, v: &str) -> Result - where - E: DeError, - { - v.parse().map_err(E::custom) - } - } + fn visit_str(self, v: &str) -> Result + where + E: DeError, + { + v.parse().map_err(E::custom) + } + } - deserializer.deserialize_str(MethodVisitor) + deserializer.deserialize_str(MethodVisitor) } fn deserialize_headers<'de, D>(deserializer: D) -> Result, D::Error> where - D: Deserializer<'de>, + D: Deserializer<'de>, { - struct HeaderVisitor; - - impl<'de> Visitor<'de> for HeaderVisitor { - type Value = HeaderMap; - - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a HeaderMap") - } - - fn visit_map(self, mut map: A) -> Result - where - A: MapAccess<'de>, - { - let mut headers = http::HeaderMap::new(); - while let Some((key, value)) = map.next_entry::, Cow<'_, str>>()? { - let header_name = key - .parse::() - .map_err(A::Error::custom)?; - let header_value = - http::header::HeaderValue::from_shared(value.into_owned().into()) - .map_err(A::Error::custom)?; - headers.append(header_name, header_value); - } - Ok(headers) - } - } - - deserializer.deserialize_map(HeaderVisitor) + struct HeaderVisitor; + + impl<'de> Visitor<'de> for HeaderVisitor { + type Value = HeaderMap; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "a HeaderMap") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut headers = http::HeaderMap::new(); + while let Some((key, value)) = map.next_entry::, Cow<'_, str>>()? { + let header_name = key + .parse::() + .map_err(A::Error::custom)?; + let header_value = http::header::HeaderValue::from_maybe_shared(value.into_owned()) + .map_err(A::Error::custom)?; + headers.append(header_name, header_value); + } + Ok(headers) + } + } + + deserializer.deserialize_map(HeaderVisitor) } impl<'a> From> for HttpRequest { - fn from(value: VercelRequest<'_>) -> Self { - let VercelRequest { - host, - path, - method, - headers, - body, - encoding, - } = value; - - // build an http::Request from a vercel_lambda::VercelRequest - let mut builder = HttpRequest::builder(); - builder.method(method); - builder.uri(format!("https://{}{}", host, path)); - - let mut req = builder - .body(match (body, encoding) { - (Some(ref b), Some(ref encoding)) if encoding == "base64" => { - // todo: document failure behavior - Body::from(::base64::decode(b.as_ref()).unwrap_or_default()) - } - (Some(b), _) => Body::from(b.into_owned()), - _ => Body::from(()), - }) - .expect("failed to build request"); - - // no builder method that sets headers in batch - let _ = mem::replace(req.headers_mut(), headers); - - req - } + fn from(value: VercelRequest<'_>) -> Self { + let VercelRequest { + host, + path, + method, + headers, + body, + encoding, + } = value; + + // build an http::Request from a vercel_lambda::VercelRequest + let builder = HttpRequest::builder() + .method(method) + .uri(format!("https://{}{}", host, path)); + + let mut req = builder + .body(match (body, encoding) { + (Some(ref b), Some(ref encoding)) if encoding == "base64" => { + // todo: document failure behavior + Body::from(::base64::decode(b.as_ref()).unwrap_or_default()) + } + (Some(b), _) => Body::from(b.into_owned()), + _ => Body::from(()), + }) + .expect("failed to build request"); + + // no builder method that sets headers in batch + let _ = mem::replace(req.headers_mut(), headers); + + req + } } diff --git a/src/response.rs b/src/response.rs index 25a7c42..eaf3b49 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,8 +1,8 @@ //! Response types use http::{ - header::{HeaderMap, HeaderValue}, - Response, + header::{HeaderMap, HeaderValue}, + Response, }; use serde::ser::{Error as SerError, SerializeMap, Serializer}; use serde_derive::Serialize; @@ -13,59 +13,59 @@ use crate::body::Body; #[derive(Serialize, Debug)] #[serde(rename_all = "camelCase")] pub(crate) struct VercelResponse { - pub status_code: u16, - #[serde( - skip_serializing_if = "HeaderMap::is_empty", - serialize_with = "serialize_headers" - )] - pub headers: HeaderMap, - #[serde(skip_serializing_if = "Option::is_none")] - pub body: Option, - #[serde(skip_serializing_if = "Option::is_none")] - pub encoding: Option, + pub status_code: u16, + #[serde( + skip_serializing_if = "HeaderMap::is_empty", + serialize_with = "serialize_headers" + )] + pub headers: HeaderMap, + #[serde(skip_serializing_if = "Option::is_none")] + pub body: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub encoding: Option, } impl Default for VercelResponse { - fn default() -> Self { - Self { - status_code: 200, - headers: Default::default(), - body: Default::default(), - encoding: Default::default(), - } - } + fn default() -> Self { + Self { + status_code: 200, + headers: Default::default(), + body: Default::default(), + encoding: Default::default(), + } + } } fn serialize_headers(headers: &HeaderMap, serializer: S) -> Result where - S: Serializer, + S: Serializer, { - let mut map = serializer.serialize_map(Some(headers.keys_len()))?; - for key in headers.keys() { - let map_value = headers[key].to_str().map_err(S::Error::custom)?; - map.serialize_entry(key.as_str(), map_value)?; - } - map.end() + let mut map = serializer.serialize_map(Some(headers.keys_len()))?; + for key in headers.keys() { + let map_value = headers[key].to_str().map_err(S::Error::custom)?; + map.serialize_entry(key.as_str(), map_value)?; + } + map.end() } impl From> for VercelResponse where - T: Into, + T: Into, { - fn from(value: Response) -> Self { - let (parts, bod) = value.into_parts(); - let (encoding, body) = match bod.into() { - Body::Empty => (None, None), - b @ Body::Text(_) => (None, Some(b)), - b @ Body::Binary(_) => (Some("base64".to_string()), Some(b)), - }; - VercelResponse { - status_code: parts.status.as_u16(), - body, - headers: parts.headers, - encoding, - } - } + fn from(value: Response) -> Self { + let (parts, bod) = value.into_parts(); + let (encoding, body) = match bod.into() { + Body::Empty => (None, None), + b @ Body::Text(_) => (None, Some(b)), + b @ Body::Binary(_) => (Some("base64".to_string()), Some(b)), + }; + VercelResponse { + status_code: parts.status.as_u16(), + body, + headers: parts.headers, + encoding, + } + } } /// A conversion of self into a `Response` @@ -85,38 +85,38 @@ where /// ); /// ``` pub trait IntoResponse { - /// Return a translation of `self` into a `Response` - fn into_response(self) -> Response; + /// Return a translation of `self` into a `Response` + fn into_response(self) -> Response; } impl IntoResponse for Response where - B: Into, + B: Into, { - fn into_response(self) -> Response { - let (parts, body) = self.into_parts(); - Response::from_parts(parts, body.into()) - } + fn into_response(self) -> Response { + let (parts, body) = self.into_parts(); + Response::from_parts(parts, body.into()) + } } impl IntoResponse for B where - B: Into, + B: Into, { - fn into_response(self) -> Response { - Response::new(self.into()) - } + fn into_response(self) -> Response { + Response::new(self.into()) + } } impl IntoResponse for serde_json::Value { - fn into_response(self) -> Response { - Response::builder() - .header(http::header::CONTENT_TYPE, "application/json") - .body( - serde_json::to_string(&self) - .expect("unable to serialize serde_json::Value") - .into(), - ) - .expect("unable to build http::Response") - } + fn into_response(self) -> Response { + Response::builder() + .header(http::header::CONTENT_TYPE, "application/json") + .body( + serde_json::to_string(&self) + .expect("unable to serialize serde_json::Value") + .into(), + ) + .expect("unable to build http::Response") + } } diff --git a/src/strmap.rs b/src/strmap.rs index dba07c6..4f6dc0f 100644 --- a/src/strmap.rs +++ b/src/strmap.rs @@ -1,7 +1,7 @@ use std::{ - collections::{hash_map::Keys, HashMap}, - fmt, - sync::Arc, + collections::{hash_map::Keys, HashMap}, + fmt, + sync::Arc, }; use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; @@ -11,80 +11,80 @@ use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; pub struct StrMap(pub(crate) Arc>); impl StrMap { - /// Return a named value where available - pub fn get(&self, key: &str) -> Option<&str> { - self.0.get(key).map(|value| value.as_ref()) - } + /// Return a named value where available + pub fn get(&self, key: &str) -> Option<&str> { + self.0.get(key).map(|value| value.as_ref()) + } - /// Return true if the underlying map is empty - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } + /// Return true if the underlying map is empty + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } - /// Return an iterator over keys and values - pub fn iter(&self) -> StrMapIter<'_> { - StrMapIter { - data: self, - keys: self.0.keys(), - } - } + /// Return an iterator over keys and values + pub fn iter(&self) -> StrMapIter<'_> { + StrMapIter { + data: self, + keys: self.0.keys(), + } + } } impl Clone for StrMap { - fn clone(&self) -> Self { - // only clone the inner data - StrMap(self.0.clone()) - } + fn clone(&self) -> Self { + // only clone the inner data + StrMap(self.0.clone()) + } } impl From> for StrMap { - fn from(inner: HashMap) -> Self { - StrMap(Arc::new(inner)) - } + fn from(inner: HashMap) -> Self { + StrMap(Arc::new(inner)) + } } /// A read only reference to `StrMap` key and value slice pairings pub struct StrMapIter<'a> { - data: &'a StrMap, - keys: Keys<'a, String, String>, + data: &'a StrMap, + keys: Keys<'a, String, String>, } impl<'a> Iterator for StrMapIter<'a> { - type Item = (&'a str, &'a str); + type Item = (&'a str, &'a str); - #[inline] - fn next(&mut self) -> Option<(&'a str, &'a str)> { - self.keys - .next() - .and_then(|k| self.data.get(k).map(|v| (k.as_str(), v))) - } + #[inline] + fn next(&mut self) -> Option<(&'a str, &'a str)> { + self.keys + .next() + .and_then(|k| self.data.get(k).map(|v| (k.as_str(), v))) + } } impl<'de> Deserialize<'de> for StrMap { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - struct StrMapVisitor; + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct StrMapVisitor; - impl<'de> Visitor<'de> for StrMapVisitor { - type Value = StrMap; + impl<'de> Visitor<'de> for StrMapVisitor { + type Value = StrMap; - fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a StrMap") - } + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(formatter, "a StrMap") + } - fn visit_map(self, mut map: A) -> Result - where - A: MapAccess<'de>, - { - let mut inner = HashMap::new(); - while let Some((key, value)) = map.next_entry()? { - inner.insert(key, value); - } - Ok(StrMap(Arc::new(inner))) - } - } + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut inner = HashMap::new(); + while let Some((key, value)) = map.next_entry()? { + inner.insert(key, value); + } + Ok(StrMap(Arc::new(inner))) + } + } - deserializer.deserialize_map(StrMapVisitor) - } + deserializer.deserialize_map(StrMapVisitor) + } } From 6451cd608a65f8abc89a1d454e62879fa6b43e56 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Fri, 17 Sep 2021 20:15:40 +0800 Subject: [PATCH 2/6] Add async handler example to readme --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index aef8488..457a7a7 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,28 @@ fn main() -> Result<(), Box> { } ``` +Async fn can also be used as handler +```rust +use http::{StatusCode}; +use vercel_lambda::{lambda, error::VercelError, IntoResponse, Request, Response}; +use std::error::Error; + +async fn handler(_: Request) -> Result { + let response = Response::builder() + .status(StatusCode::OK) + .header("Content-Type", "text/plain") + .body("Hello World") + .expect("Internal Server Error"); + + Ok(response) +} + +// Start the runtime with the handler +fn main() -> Result<(), Box> { + Ok(lambda_async!(handler)) +} +``` + Finally, we need an `api/Cargo.toml` file: ```toml From 3e7961337e5fdf97d5b0e38f67b79153f6754eba Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Fri, 17 Sep 2021 22:37:20 +0800 Subject: [PATCH 3/6] fix tokio runtime builder --- Cargo.toml | 2 +- src/lib.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 34e7f2f..9b63724 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ log = "0.4" serde = "1" serde_derive = "1" serde_json = "1" -tokio = {version = "1.11", optional = true} +tokio = {version = "1.11", optional = true, features = ["full"]} [dev-dependencies] anyhow = "1" diff --git a/src/lib.rs b/src/lib.rs index d41bd5c..073023f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -156,9 +156,11 @@ fn get_runtime(runtime: Option) -> tokio::runtime::Runt match runtime { Some(rt) => rt, _ => tokio::runtime::Builder::new_multi_thread() + .enable_all() .build() .unwrap_or_else(|_| { tokio::runtime::Builder::new_current_thread() + .enable_all() .build() .unwrap() }), From 5e3d89dce3ea40899292917ceb811f0588b52f01 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Wed, 22 Sep 2021 05:04:07 +0800 Subject: [PATCH 4/6] tokio 1.12 --- Cargo.toml | 4 ++-- README.md | 2 +- package/CHANGELOG.md | 2 +- src/request.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9b63724..aaac6c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,8 +31,8 @@ log = "0.4" serde = "1" serde_derive = "1" serde_json = "1" -tokio = {version = "1.11", optional = true, features = ["full"]} +tokio = {version = "1.12", optional = true, features = ["full"]} [dev-dependencies] anyhow = "1" -tokio = "1.11" +tokio = "1.12" diff --git a/README.md b/README.md index 457a7a7..1005c2c 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ fn main() -> Result<(), Box> { Async fn can also be used as handler ```rust use http::{StatusCode}; -use vercel_lambda::{lambda, error::VercelError, IntoResponse, Request, Response}; +use vercel_lambda::{lambda_async, error::VercelError, IntoResponse, Request, Response}; use std::error::Error; async fn handler(_: Request) -> Result { diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index 17076f0..3867774 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -6,7 +6,7 @@ - Add async handler fn support - Make tokio an optional dependency behind feature `runtime` (default on) -- Upgrade tokio to 1.11 +- Upgrade tokio to 1.12 - Upgrade http to 0.2 - Upgrade lambda_runtime to 0.4 diff --git a/src/request.rs b/src/request.rs index 5b2ea80..de1dd45 100644 --- a/src/request.rs +++ b/src/request.rs @@ -25,7 +25,7 @@ pub(crate) struct VercelRequest<'a> { #[derive(Deserialize, Debug, Default)] pub(crate) struct VercelEvent { #[serde(rename = "Action")] - action: String, + _action: String, pub(crate) body: String, } From 0b0471c5086302422c026f321834c3d67474ee06 Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Tue, 16 Nov 2021 19:41:55 +0800 Subject: [PATCH 5/6] rust 2021 --- .gitignore | 2 +- Cargo.toml | 7 +++---- package/CHANGELOG.md | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 12ec4c1..5273019 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ node_modules/ .vercel/ fixtures/**/vercel.json -cargo.lock +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index aaac6c3..8829091 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,7 @@ keywords = ["Vercel", "Rust", "Serverless", "Functions"] license = "MIT" repository = "https://github.com/vercel-community/rust" -edition = "2018" -resolver = "2" +edition = "2021" include = [ "src/*.rs", @@ -31,8 +30,8 @@ log = "0.4" serde = "1" serde_derive = "1" serde_json = "1" -tokio = {version = "1.12", optional = true, features = ["full"]} +tokio = {version = "1.14", optional = true, features = ["full"]} [dev-dependencies] anyhow = "1" -tokio = "1.12" +tokio = "1.14" diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index 3867774..d44ab7a 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -6,9 +6,10 @@ - Add async handler fn support - Make tokio an optional dependency behind feature `runtime` (default on) -- Upgrade tokio to 1.12 +- Upgrade tokio to 1.14 - Upgrade http to 0.2 - Upgrade lambda_runtime to 0.4 +- Upgrade to rust 2021 ## 0.2.0 From 5888c4e91a8e162b19bc5190fa8242bb8a11ca6a Mon Sep 17 00:00:00 2001 From: hanabi1224 Date: Thu, 8 Dec 2022 03:16:11 +0800 Subject: [PATCH 6/6] upgrade lambda_runtime --- Cargo.toml | 6 +++--- package/CHANGELOG.md | 4 ++-- src/body.rs | 4 ++-- src/lib.rs | 25 ++++++++++++------------- src/strmap.rs | 2 +- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8829091..7d8cd24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,13 +25,13 @@ runtime = ["tokio"] [dependencies] base64 = "0.13" http = "0.2" -lambda_runtime = "0.4" +lambda_runtime = "0.7" log = "0.4" serde = "1" serde_derive = "1" serde_json = "1" -tokio = {version = "1.14", optional = true, features = ["full"]} +tokio = {version = "1.23", optional = true, features = ["full"]} [dev-dependencies] anyhow = "1" -tokio = "1.14" +tokio = "1.17" diff --git a/package/CHANGELOG.md b/package/CHANGELOG.md index d44ab7a..015f7b2 100644 --- a/package/CHANGELOG.md +++ b/package/CHANGELOG.md @@ -6,9 +6,9 @@ - Add async handler fn support - Make tokio an optional dependency behind feature `runtime` (default on) -- Upgrade tokio to 1.14 +- Upgrade tokio to 1.23 - Upgrade http to 0.2 -- Upgrade lambda_runtime to 0.4 +- Upgrade lambda_runtime to 0.7 - Upgrade to rust 2021 ## 0.2.0 diff --git a/src/body.rs b/src/body.rs index b4519f9..64fcb5c 100644 --- a/src/body.rs +++ b/src/body.rs @@ -54,7 +54,7 @@ use serde::ser::{Error as SerError, Serialize, Serializer}; /// _ => false /// }) /// ``` -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum Body { /// An empty body Empty, @@ -177,7 +177,7 @@ impl AsRef<[u8]> for Body { } } -impl<'a> Serialize for Body { +impl Serialize for Body { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/src/lib.rs b/src/lib.rs index 073023f..dcd2757 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ pub use http::{self, Response}; -use lambda_runtime::{self as lambda, handler_fn, Context}; +use lambda_runtime::{self, service_fn, LambdaEvent}; use log::{self, debug, error}; use serde_json::Error; use std::future::Future; @@ -51,22 +51,21 @@ where E: Into, R: IntoResponse, { - let func = |e: VercelEvent, ctx: Context| process_vercel_request(f, e, ctx); - let func = handler_fn(func); - lambda::run(func).await + let func = |request: LambdaEvent| process_vercel_request(request, f); + let service = service_fn(func); + lambda_runtime::run(service).await } async fn process_vercel_request( + request: LambdaEvent, f: fn(http::Request) -> Result, - e: VercelEvent, - _ctx: Context, ) -> Result where B: From, E: Into, R: IntoResponse, { - let parse_result: Result = serde_json::from_str(&e.body); + let parse_result: Result = serde_json::from_str(&request.payload.body); match parse_result { Ok(req) => { debug!("Deserialized Vercel proxy request successfully"); @@ -116,15 +115,15 @@ where E: Into, R: IntoResponse, { - let func = |e: VercelEvent, ctx: Context| process_vercel_request_with_async_handler(f, e, ctx); - let func = handler_fn(func); - lambda::run(func).await + let func = + |request: LambdaEvent| process_vercel_request_with_async_handler(request, f); + let service = service_fn(func); + lambda_runtime::run(service).await } async fn process_vercel_request_with_async_handler( + request: LambdaEvent, f: fn(http::Request) -> F, - e: VercelEvent, - _ctx: Context, ) -> Result where F: Future>, @@ -132,7 +131,7 @@ where E: Into, R: IntoResponse, { - let parse_result: Result = serde_json::from_str(&e.body); + let parse_result: Result = serde_json::from_str(&request.payload.body); match parse_result { Ok(req) => { debug!("Deserialized Vercel proxy request successfully"); diff --git a/src/strmap.rs b/src/strmap.rs index 4f6dc0f..2790ac7 100644 --- a/src/strmap.rs +++ b/src/strmap.rs @@ -7,7 +7,7 @@ use std::{ use serde::de::{Deserialize, Deserializer, MapAccess, Visitor}; /// A read-only view into a map of string data -#[derive(Default, Debug, PartialEq)] +#[derive(Default, Debug, PartialEq, Eq)] pub struct StrMap(pub(crate) Arc>); impl StrMap {