summaryrefslogtreecommitdiffstats
path: root/vendor/maybe-async
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:35 +0000
commit7e5d7eea9c580ef4b41a765bde624af431942b96 (patch)
tree2c0d9ca12878fc4525650aa4e54d77a81a07cc09 /vendor/maybe-async
parentAdding debian version 1.70.0+dfsg1-9. (diff)
downloadrustc-7e5d7eea9c580ef4b41a765bde624af431942b96.tar.xz
rustc-7e5d7eea9c580ef4b41a765bde624af431942b96.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/maybe-async')
-rw-r--r--vendor/maybe-async/.cargo-checksum.json1
-rw-r--r--vendor/maybe-async/CHANGELOG.md61
-rw-r--r--vendor/maybe-async/Cargo.lock740
-rw-r--r--vendor/maybe-async/Cargo.toml69
-rw-r--r--vendor/maybe-async/LICENSE19
-rw-r--r--vendor/maybe-async/README.md270
-rw-r--r--vendor/maybe-async/examples/service_client.rs75
-rw-r--r--vendor/maybe-async/src/lib.rs621
-rw-r--r--vendor/maybe-async/src/parse.rs49
-rw-r--r--vendor/maybe-async/src/visit.rs199
-rw-r--r--vendor/maybe-async/tests/test.rs15
-rw-r--r--vendor/maybe-async/tests/ui/01-maybe-async.rs81
-rw-r--r--vendor/maybe-async/tests/ui/02-must-be-async.rs96
-rw-r--r--vendor/maybe-async/tests/ui/03-must-be-sync.rs74
-rw-r--r--vendor/maybe-async/tests/ui/04-unit-test-util.rs38
-rw-r--r--vendor/maybe-async/tests/ui/05-replace-future-generic-type-with-output.rs34
-rw-r--r--vendor/maybe-async/tests/ui/06-sync_impl_async_impl.rs44
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/01-empty-test.rs17
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/01-empty-test.stderr7
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/02-unknown-path.rs17
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/02-unknown-path.stderr5
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/03-async-gt2.rs16
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/03-async-gt2.stderr5
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.rs17
-rw-r--r--vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.stderr5
-rw-r--r--vendor/maybe-async/tests/unit-test-util.rs30
26 files changed, 2605 insertions, 0 deletions
diff --git a/vendor/maybe-async/.cargo-checksum.json b/vendor/maybe-async/.cargo-checksum.json
new file mode 100644
index 000000000..f1dbc3710
--- /dev/null
+++ b/vendor/maybe-async/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"96131942910a2d931bf38266e44afe048783ea705a650156fcf484f48b9d878e","Cargo.lock":"38dbb54210cbed1a1f884d840dc51d24e3576563d943ee3fe32ecb7084bbe6c8","Cargo.toml":"4b183fe9af8bba7dc174e173bfa2cf00c487cfe184c6ec404d452ceab8e73d11","LICENSE":"233be68ab89eaccff940b48aa638fbecbf060f4da9148837f78d0c3146b1dd30","README.md":"6b849cb7c07f3e7a696d43c0af93acb472806dd3b5d1b37b0cdf46de5744c761","examples/service_client.rs":"4f1b5e302cbfc96a89f49154ea9e95ccf18526a33ceb660d34b6ffe92eaf3deb","src/lib.rs":"ddf871dd7f10f9fafc82dc8ab4faf57c8589a2866602ae3b16299a147573755a","src/parse.rs":"73ba694e0fd724d28c84662e7c90280a685fad8ccc520f04532e924bd6ccfc40","src/visit.rs":"e60068d7b4bc83268a778183cb2f01020269d8a32ee90f9b495a09cc0cf53b72","tests/test.rs":"06d71ea5e81a46a9f0be84230aafbdab15c13ba61d5579d403f736574daabf7b","tests/ui/01-maybe-async.rs":"cf14908537436198b639e2efed05a0f835f51a763d2fe0ca4b75780193b44023","tests/ui/02-must-be-async.rs":"e4fb101a4834dc93f19adb153e5d2aa6cf52dc2bce41b556d9bf21e173136a89","tests/ui/03-must-be-sync.rs":"5608d152739dabb4b2dc55967d82072cb092322ac0a51077dc444fdfde3191fa","tests/ui/04-unit-test-util.rs":"04f3f029900e2f5d086961d753ddf10f122dbebc709618303f83fab23f6d4c29","tests/ui/05-replace-future-generic-type-with-output.rs":"481f4afb978ffc7cd756765f72e3456813dc8748ada57ac200e1a02a3d9562c3","tests/ui/06-sync_impl_async_impl.rs":"a8e8ec6db193172061eed098396ab9a0b6b03707f9854eae8a5df45c2340c809","tests/ui/test_fail/01-empty-test.rs":"d87f35ae690dcd2851fea2bb8f15745bb86aa9301efd642f30aa6018654dcebb","tests/ui/test_fail/01-empty-test.stderr":"7bb5274635582533ba5a761cdb36a211c382ff57c973352f4a7ac5a6953f08b4","tests/ui/test_fail/02-unknown-path.rs":"fc7cd52d4d7107c779980386ed5f4d133a1dcdf74261fd0ea0df53d03d5c8b1b","tests/ui/test_fail/02-unknown-path.stderr":"28374dc1c4c44f6ba7eedff576e43c3d724dc4f204040d8cec5773e5f997a44b","tests/ui/test_fail/03-async-gt2.rs":"336d628e829e6fdf41764b3d13afe5d41d1100f46bfedb61b74a4723aecb0d40","tests/ui/test_fail/03-async-gt2.stderr":"677f322ece465459410c7fdc76001f76869f9b81906096b0ece6fd97247a1f1f","tests/ui/test_fail/04-bad-sync-cond.rs":"8698ab272081cb571fcdd163a847f815b153125932ee1837829778dbe769826b","tests/ui/test_fail/04-bad-sync-cond.stderr":"bd8bdf65b1cbba7610441341dd9212da066cdd2ebee65f83a772b0921cde1e38","tests/unit-test-util.rs":"a9e09c54e14c07e5d9f33f245d583455d9324be2e826b20ce2b882f990db937e"},"package":"0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305"} \ No newline at end of file
diff --git a/vendor/maybe-async/CHANGELOG.md b/vendor/maybe-async/CHANGELOG.md
new file mode 100644
index 000000000..60fc684e2
--- /dev/null
+++ b/vendor/maybe-async/CHANGELOG.md
@@ -0,0 +1,61 @@
+# Changelog
+
+All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+### [0.2.7](https://github.com/fMeow/maybe-async-rs/compare/v0.2.6...v0.2.7) (2023-02-01)
+
+
+### Features
+
+* allow `maybe_async` on static ([a08b112](https://github.com/fMeow/maybe-async-rs/commit/a08b11218bab0d1db304a4f68e0230c022632168))
+
+
+### Bug Fixes
+
+* applying to pub(crate) trait fail ([8cf762f](https://github.com/fMeow/maybe-async-rs/commit/8cf762fdeb1d316716fa01fb2525e5a6f5d25987))
+
+### [0.2.6](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.4...v0.2.6) (2021-05-28)
+
+
+### Bug Fixes
+
+* remove async test if condition not match ([0089daa](https://github.com/guoli-lyu/maybe-async-rs/commit/0089daad6e3419e11d123e8c5c87a1139880027f))
+* test is removed when is_sync ([377815a](https://github.com/guoli-lyu/maybe-async-rs/commit/377815a7a81efc4a0332cc2716a7d603b350ff03))
+
+### [0.2.5](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.4...v0.2.5) (2021-05-28)
+
+
+### Bug Fixes
+
+* remove async test if condition not match ([0c49246](https://github.com/guoli-lyu/maybe-async-rs/commit/0c49246a3245773faff482f6b42d66522d2af208))
+
+### [0.2.4](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.3...v0.2.4) (2021-03-28)
+
+
+### Features
+
+* replace generic type of Future with Output ([f296cc0](https://github.com/guoli-lyu/maybe-async-rs/commit/f296cc05c90923ae3a3eeea3c5173d06d642c2ab))
+* search trait bound that ends with `Future` ([3508ff2](https://github.com/guoli-lyu/maybe-async-rs/commit/3508ff2987cce61808297aa920c522e0f2012a8a))
+
+### [0.2.3](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.2...v0.2.3) (2021-03-27)
+
+
+### Bug Fixes
+
+* enable full feature gate for syn ([614c085](https://github.com/guoli-lyu/maybe-async-rs/commit/614c085444caf6d0d493422ca20f8ed3b86b7315))
+
+### [0.2.2](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.1...v0.2.2) (2020-10-19)
+
+
+### Features
+
+* avoid extra parenthesis and braces ([8d146f9](https://github.com/guoli-lyu/maybe-async-rs/commit/8d146f9a9234339de1ef6b9f7ffd44421a8d6c68))
+* remove parenthesis wrap in await ([bc5f460](https://github.com/guoli-lyu/maybe-async-rs/commit/bc5f46078bfb5ccc1599570303aa72a84cc5e2d7))
+* wrap await expr into block instead of paren ([5c4232a](https://github.com/guoli-lyu/maybe-async-rs/commit/5c4232a07035e9c2d4add280cc5b090a7bde471b))
+
+### [0.2.1](https://github.com/guoli-lyu/maybe-async-rs/compare/v0.2.0...v0.2.1) (2020-10-05)
+
+
+### Bug Fixes
+
+* allow unused_paren when convert to sync ([242ded2](https://github.com/guoli-lyu/maybe-async-rs/commit/242ded2fb9f1cc3c883e0f39a081a555e7a74198))
diff --git a/vendor/maybe-async/Cargo.lock b/vendor/maybe-async/Cargo.lock
new file mode 100644
index 000000000..8657b172d
--- /dev/null
+++ b/vendor/maybe-async/Cargo.lock
@@ -0,0 +1,740 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "async-attributes"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "async-channel"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833"
+dependencies = [
+ "concurrent-queue",
+ "event-listener",
+ "futures-core",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b"
+dependencies = [
+ "async-lock",
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "slab",
+]
+
+[[package]]
+name = "async-global-executor"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
+dependencies = [
+ "async-channel",
+ "async-executor",
+ "async-io",
+ "async-lock",
+ "blocking",
+ "futures-lite",
+ "once_cell",
+]
+
+[[package]]
+name = "async-io"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794"
+dependencies = [
+ "async-lock",
+ "autocfg",
+ "concurrent-queue",
+ "futures-lite",
+ "libc",
+ "log",
+ "parking",
+ "polling",
+ "slab",
+ "socket2",
+ "waker-fn",
+ "windows-sys",
+]
+
+[[package]]
+name = "async-lock"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
+dependencies = [
+ "event-listener",
+ "futures-lite",
+]
+
+[[package]]
+name = "async-std"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
+dependencies = [
+ "async-attributes",
+ "async-channel",
+ "async-global-executor",
+ "async-io",
+ "async-lock",
+ "crossbeam-utils",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-lite",
+ "gloo-timers",
+ "kv-log-macro",
+ "log",
+ "memchr",
+ "once_cell",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+ "wasm-bindgen-futures",
+]
+
+[[package]]
+name = "async-task"
+version = "4.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
+
+[[package]]
+name = "async-trait"
+version = "0.1.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "atomic-waker"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599"
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "basic-toml"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e819b667739967cd44d308b8c7b71305d8bb0729ac44a248aa08f33d01950b4"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "blocking"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8"
+dependencies = [
+ "async-channel",
+ "async-lock",
+ "async-task",
+ "atomic-waker",
+ "fastrand",
+ "futures-lite",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "concurrent-queue"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e"
+dependencies = [
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "ctor"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
+dependencies = [
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "dissimilar"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "210ec60ae7d710bed8683e333e9d2855a8a56a3e9892b38bad3bb0d4d29b0d5e"
+
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
+[[package]]
+name = "fastrand"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
+
+[[package]]
+name = "futures-io"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
+
+[[package]]
+name = "futures-lite"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "gloo-timers"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "kv-log-macro"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.139"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+ "value-bag",
+]
+
+[[package]]
+name = "maybe-async"
+version = "0.2.7"
+dependencies = [
+ "async-std",
+ "async-trait",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "tokio",
+ "trybuild",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "num_cpus"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+
+[[package]]
+name = "parking"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "polling"
+version = "2.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6"
+dependencies = [
+ "autocfg",
+ "cfg-if",
+ "libc",
+ "log",
+ "wepoll-ffi",
+ "windows-sys",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
+
+[[package]]
+name = "serde"
+version = "1.0.152"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.152"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.91"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "tokio"
+version = "1.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
+dependencies = [
+ "autocfg",
+ "num_cpus",
+ "pin-project-lite",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "trybuild"
+version = "1.0.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44da5a6f2164c8e14d3bbc0657d69c5966af9f5f6930d4f600b1f5c4a673413"
+dependencies = [
+ "basic-toml",
+ "dissimilar",
+ "glob",
+ "once_cell",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "termcolor",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+
+[[package]]
+name = "value-bag"
+version = "1.0.0-alpha.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55"
+dependencies = [
+ "ctor",
+ "version_check",
+]
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "waker-fn"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "wepoll-ffi"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[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-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[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 = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/vendor/maybe-async/Cargo.toml b/vendor/maybe-async/Cargo.toml
new file mode 100644
index 000000000..ef8bd23de
--- /dev/null
+++ b/vendor/maybe-async/Cargo.toml
@@ -0,0 +1,69 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "maybe-async"
+version = "0.2.7"
+authors = ["Guoli Lyu <guoli-lv@hotmail.com>"]
+description = "A procedure macro to unify SYNC and ASYNC implementation"
+documentation = "https://docs.rs/maybe-async"
+readme = "README.md"
+keywords = [
+ "maybe",
+ "async",
+ "futures",
+ "macros",
+ "proc_macro",
+]
+license = "MIT"
+repository = "https://github.com/fMeow/maybe-async-rs"
+
+[lib]
+proc-macro = true
+
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0"
+features = [
+ "visit-mut",
+ "full",
+]
+
+[dev-dependencies.async-std]
+version = "1"
+features = ["attributes"]
+
+[dev-dependencies.async-trait]
+version = "0.1"
+
+[dev-dependencies.tokio]
+version = "1"
+features = [
+ "macros",
+ "rt-multi-thread",
+]
+
+[dev-dependencies.trybuild]
+version = "1"
+features = ["diff"]
+
+[features]
+default = []
+is_sync = []
+
+[badges.maintenance]
+status = "actively-developed"
diff --git a/vendor/maybe-async/LICENSE b/vendor/maybe-async/LICENSE
new file mode 100644
index 000000000..db45620c6
--- /dev/null
+++ b/vendor/maybe-async/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Guoli Lyu
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/vendor/maybe-async/README.md b/vendor/maybe-async/README.md
new file mode 100644
index 000000000..e1dc385d3
--- /dev/null
+++ b/vendor/maybe-async/README.md
@@ -0,0 +1,270 @@
+# Maybe-Async Procedure Macro
+
+**Why bother writing similar code twice for blocking and async code?**
+
+[![Build Status](https://github.com/fMeow/maybe-async-rs/workflows/CI%20%28Linux%29/badge.svg?branch=main)](https://github.com/fMeow/maybe-async-rs/actions)
+[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
+[![Latest Version](https://img.shields.io/crates/v/maybe-async.svg)](https://crates.io/crates/maybe-async)
+[![maybe-async](https://docs.rs/maybe-async/badge.svg)](https://docs.rs/maybe-async)
+
+When implementing both sync and async versions of API in a crate, most API
+of the two version are almost the same except for some async/await keyword.
+
+`maybe-async` help unifying async and sync implementation by **procedural
+macro**.
+- Write async code with normal `async`, `await`, and let `maybe_async`
+ handles
+those `async` and `await` when you need a blocking code.
+- Switch between sync and async by toggling `is_sync` feature gate in
+ `Cargo.toml`.
+- use `must_be_async` and `must_be_sync` to keep code in specified version
+- use `impl_async` and `impl_sync` to only compile code block on specified
+ version
+- A handy macro to unify unit test code is also provided.
+
+These procedural macros can be applied to the following codes:
+- trait item declaration
+- trait implmentation
+- function definition
+- struct definition
+
+**RECOMMENDATION**: Enable **resolver ver2** in your crate, which is
+introduced in Rust 1.51. If not, two crates in dependency with conflict
+version (one async and another blocking) can fail complilation.
+
+
+## Motivation
+
+The async/await language feature alters the async world of rust.
+Comparing with the map/and_then style, now the async code really resembles
+sync version code.
+
+In many crates, the async and sync version of crates shares the same API,
+but the minor difference that all async code must be awaited prevent the
+unification of async and sync code. In other words, we are forced to write
+an async and an sync implementation repectively.
+
+## Macros in Detail
+
+`maybe-async` offers 4 set of attribute macros: `maybe_async`,
+`sync_impl`/`async_impl`, `must_be_sync`/`must_be_async`, and `test`.
+
+To use `maybe-async`, we must know which block of codes is only used on
+blocking implementation, and which on async. These two implementation should
+share the same function signatures except for async/await keywords, and use
+`sync_impl` and `async_impl` to mark these implementation.
+
+Use `maybe_async` macro on codes that share the same API on both async and
+blocking code except for async/await keywords. And use feature gate
+`is_sync` in `Cargo.toml` to toggle between async and blocking code.
+
+- `maybe_async`
+
+ Offers a unified feature gate to provide sync and async conversion on
+ demand by feature gate `is_sync`, with **async first** policy.
+
+ Want to keep async code? add `maybe_async` in dependencies with default
+ features, which means `maybe_async` is the same as `must_be_async`:
+
+ ```toml
+ [dependencies]
+ maybe_async = "0.2"
+ ```
+
+ Wanna convert async code to sync? Add `maybe_async` to dependencies with
+ an `is_sync` feature gate. In this way, `maybe_async` is the same as
+ `must_be_sync`:
+
+ ```toml
+ [dependencies]
+ maybe_async = { version = "0.2", features = ["is_sync"] }
+ ```
+
+ Not all async traits need futures that are `dyn Future + Send`.
+ To avoid having "Send" and "Sync" bounds placed on the async trait
+ methods, invoke the maybe_async macro as #[maybe_async(?Send)] on both
+ the trait and the impl blocks.
+
+
+- `must_be_async`
+
+ **Keep async**. Add `async_trait` attribute macro for trait declaration
+ or implementation to bring async fn support in traits.
+
+ To avoid having "Send" and "Sync" bounds placed on the async trait
+ methods, invoke the maybe_async macro as #[must_be_async(?Send)].
+
+- `must_be_sync`
+
+ **Convert to sync code**. Convert the async code into sync code by
+ removing all `async move`, `async` and `await` keyword
+
+
+- `sync_impl`
+
+ An sync implementation should on compile on blocking implementation and
+must simply disappear when we want async version.
+
+ Although most of the API are almost the same, there definitely come to a
+ point when the async and sync version should differ greatly. For
+ example, a MongoDB client may use the same API for async and sync
+ verison, but the code to actually send reqeust are quite different.
+
+ Here, we can use `sync_impl` to mark a synchronous implementation, and a
+ sync implementation shoule disappear when we want async version.
+
+- `async_impl`
+
+ An async implementation should on compile on async implementation and
+must simply disappear when we want sync version.
+
+ To avoid having "Send" and "Sync" bounds placed on the async trait
+ methods, invoke the maybe_async macro as #[async_impl(?Send)].
+
+
+- `test`
+
+ Handy macro to unify async and sync **unit and e2e test** code.
+
+ You can specify the condition to compile to sync test code
+ and also the conditions to compile to async test code with given test
+ macro, e.x. `tokio::test`, `async_std::test` and etc. When only sync
+ condition is specified,the test code only compiles when sync condition
+ is met.
+
+ ```rust
+ #[maybe_async::test(
+ feature="is_sync",
+ async(all(not(feature="is_sync"), feature="async_std"), async_std::test),
+ async(all(not(feature="is_sync"), feature="tokio"), tokio::test)
+ )]
+ async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+ }
+ ```
+
+## What's Under the Hook
+
+`maybe-async` compiles your code in different way with the `is_sync` feature
+gate. It remove all `await` and `async` keywords in your code under
+`maybe_async` macro and conditionally compiles codes under `async_impl` and
+`sync_impl`.
+
+Here is an detailed example on what's going on whe the `is_sync` feature
+gate set or not.
+
+```rust
+#[maybe_async::maybe_async(?Send)]
+trait A {
+ async fn async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+struct Foo;
+
+#[maybe_async::maybe_async(?Send)]
+impl A for Foo {
+ async fn async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+#[maybe_async::maybe_async]
+async fn maybe_async_fn() -> Result<(), ()> {
+ let a = Foo::async_fn_name().await?;
+
+ let b = Foo::sync_fn_name()?;
+ Ok(())
+}
+```
+
+When `maybe-async` feature gate `is_sync` is **NOT** set, the generated code
+is async code:
+
+```rust
+// Compiled code when `is_sync` is toggled off.
+#[async_trait::async_trait(?Send)]
+trait A {
+ async fn maybe_async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+struct Foo;
+
+#[async_trait::async_trait(?Send)]
+impl A for Foo {
+ async fn maybe_async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+async fn maybe_async_fn() -> Result<(), ()> {
+ let a = Foo::maybe_async_fn_name().await?;
+ let b = Foo::sync_fn_name()?;
+ Ok(())
+}
+```
+
+When `maybe-async` feature gate `is_sync` is set, all async keyword is
+ignored and yields a sync version code:
+
+```rust
+// Compiled code when `is_sync` is toggled on.
+trait A {
+ fn maybe_async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+struct Foo;
+
+impl A for Foo {
+ fn maybe_async_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+ fn sync_fn_name() -> Result<(), ()> {
+ Ok(())
+ }
+}
+
+fn maybe_async_fn() -> Result<(), ()> {
+ let a = Foo::maybe_async_fn_name()?;
+ let b = Foo::sync_fn_name()?;
+ Ok(())
+}
+```
+
+## Examples
+
+### rust client for services
+
+When implementing rust client for any services, like awz3. The higher level
+API of async and sync version is almost the same, such as creating or
+deleting a bucket, retrieving an object and etc.
+
+The example `service_client` is a proof of concept that `maybe_async` can
+actually free us from writing almost the same code for sync and async. We
+can toggle between a sync AWZ3 client and async one by `is_sync` feature
+gate when we add `maybe-async` to dependency.
+
+
+# License
+MIT \ No newline at end of file
diff --git a/vendor/maybe-async/examples/service_client.rs b/vendor/maybe-async/examples/service_client.rs
new file mode 100644
index 000000000..fec68136f
--- /dev/null
+++ b/vendor/maybe-async/examples/service_client.rs
@@ -0,0 +1,75 @@
+#![allow(dead_code, unused_variables)]
+/// To use `maybe-async`, we must know which block of codes is only used on
+/// blocking implementation, and which on async. These two implementation should
+/// share the same API except for async/await keywords, and use `sync_impl` and
+/// `async_impl` to mark these implementation.
+type Response = String;
+type Url = &'static str;
+type Method = String;
+
+/// InnerClient are used to actually send request,
+/// which differ a lot between sync and async.
+#[maybe_async::maybe_async]
+trait InnerClient {
+ async fn request(method: Method, url: Url, data: String) -> Response;
+ #[inline]
+ async fn post(url: Url, data: String) -> Response {
+ Self::request(String::from("post"), url, data).await
+ }
+ #[inline]
+ async fn delete(url: Url, data: String) -> Response {
+ Self::request(String::from("delete"), url, data).await
+ }
+}
+
+/// The higher level API for end user.
+pub struct ServiceClient;
+
+/// Synchronous implementation, only compiles when `is_sync` feature is off.
+/// Else the compiler will complain that *request is defined multiple times* and
+/// blabla.
+#[maybe_async::sync_impl]
+impl InnerClient for ServiceClient {
+ fn request(method: Method, url: Url, data: String) -> Response {
+ // your implementation for sync, like use
+ // `reqwest::blocking` to send request
+ String::from("pretend we have a response")
+ }
+}
+
+/// Asynchronous implementation, only compiles when `is_sync` feature is off.
+#[maybe_async::async_impl]
+impl InnerClient for ServiceClient {
+ async fn request(method: Method, url: Url, data: String) -> Response {
+ // your implementation for async, like use `reqwest::client`
+ // or `async_std` to send request
+ String::from("pretend we have a response")
+ }
+}
+
+/// Code of upstream API are almost the same for sync and async,
+/// except for async/await keyword.
+impl ServiceClient {
+ #[maybe_async::maybe_async]
+ async fn create_bucket(name: String) -> Response {
+ Self::post("http://correct_url4create", String::from("my_bucket")).await
+ // When `is_sync` is toggle on, this block will compiles to:
+ // Self::post("http://correct_url4create", String::from("my_bucket"))
+ }
+ #[maybe_async::maybe_async]
+ async fn delete_bucket(name: String) -> Response {
+ Self::delete("http://correct_url4delete", String::from("my_bucket")).await
+ }
+ // and another thousands of functions that interact with service side
+}
+
+#[maybe_async::sync_impl]
+fn main() {
+ let _ = ServiceClient::create_bucket("bucket".to_owned());
+}
+
+#[maybe_async::async_impl]
+#[tokio::main]
+async fn main() {
+ let _ = ServiceClient::create_bucket("bucket".to_owned()).await;
+}
diff --git a/vendor/maybe-async/src/lib.rs b/vendor/maybe-async/src/lib.rs
new file mode 100644
index 000000000..b8b43a16a
--- /dev/null
+++ b/vendor/maybe-async/src/lib.rs
@@ -0,0 +1,621 @@
+//!
+//! # Maybe-Async Procedure Macro
+//!
+//! **Why bother writing similar code twice for blocking and async code?**
+//!
+//! [![Build Status](https://github.com/fMeow/maybe-async-rs/workflows/CI%20%28Linux%29/badge.svg?branch=main)](https://github.com/fMeow/maybe-async-rs/actions)
+//! [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
+//! [![Latest Version](https://img.shields.io/crates/v/maybe-async.svg)](https://crates.io/crates/maybe-async)
+//! [![maybe-async](https://docs.rs/maybe-async/badge.svg)](https://docs.rs/maybe-async)
+//!
+//! When implementing both sync and async versions of API in a crate, most API
+//! of the two version are almost the same except for some async/await keyword.
+//!
+//! `maybe-async` help unifying async and sync implementation by **procedural
+//! macro**.
+//! - Write async code with normal `async`, `await`, and let `maybe_async`
+//! handles
+//! those `async` and `await` when you need a blocking code.
+//! - Switch between sync and async by toggling `is_sync` feature gate in
+//! `Cargo.toml`.
+//! - use `must_be_async` and `must_be_sync` to keep code in specified version
+//! - use `impl_async` and `impl_sync` to only compile code block on specified
+//! version
+//! - A handy macro to unify unit test code is also provided.
+//!
+//! These procedural macros can be applied to the following codes:
+//! - trait item declaration
+//! - trait implmentation
+//! - function definition
+//! - struct definition
+//!
+//! **RECOMMENDATION**: Enable **resolver ver2** in your crate, which is
+//! introduced in Rust 1.51. If not, two crates in dependency with conflict
+//! version (one async and another blocking) can fail complilation.
+//!
+//!
+//! ## Motivation
+//!
+//! The async/await language feature alters the async world of rust.
+//! Comparing with the map/and_then style, now the async code really resembles
+//! sync version code.
+//!
+//! In many crates, the async and sync version of crates shares the same API,
+//! but the minor difference that all async code must be awaited prevent the
+//! unification of async and sync code. In other words, we are forced to write
+//! an async and an sync implementation repectively.
+//!
+//! ## Macros in Detail
+//!
+//! `maybe-async` offers 4 set of attribute macros: `maybe_async`,
+//! `sync_impl`/`async_impl`, `must_be_sync`/`must_be_async`, and `test`.
+//!
+//! To use `maybe-async`, we must know which block of codes is only used on
+//! blocking implementation, and which on async. These two implementation should
+//! share the same function signatures except for async/await keywords, and use
+//! `sync_impl` and `async_impl` to mark these implementation.
+//!
+//! Use `maybe_async` macro on codes that share the same API on both async and
+//! blocking code except for async/await keywords. And use feature gate
+//! `is_sync` in `Cargo.toml` to toggle between async and blocking code.
+//!
+//! - `maybe_async`
+//!
+//! Offers a unified feature gate to provide sync and async conversion on
+//! demand by feature gate `is_sync`, with **async first** policy.
+//!
+//! Want to keep async code? add `maybe_async` in dependencies with default
+//! features, which means `maybe_async` is the same as `must_be_async`:
+//!
+//! ```toml
+//! [dependencies]
+//! maybe_async = "0.2"
+//! ```
+//!
+//! Wanna convert async code to sync? Add `maybe_async` to dependencies with
+//! an `is_sync` feature gate. In this way, `maybe_async` is the same as
+//! `must_be_sync`:
+//!
+//! ```toml
+//! [dependencies]
+//! maybe_async = { version = "0.2", features = ["is_sync"] }
+//! ```
+//!
+//! Not all async traits need futures that are `dyn Future + Send`.
+//! To avoid having "Send" and "Sync" bounds placed on the async trait
+//! methods, invoke the maybe_async macro as #[maybe_async(?Send)] on both
+//! the trait and the impl blocks.
+//!
+//!
+//! - `must_be_async`
+//!
+//! **Keep async**. Add `async_trait` attribute macro for trait declaration
+//! or implementation to bring async fn support in traits.
+//!
+//! To avoid having "Send" and "Sync" bounds placed on the async trait
+//! methods, invoke the maybe_async macro as #[must_be_async(?Send)].
+//!
+//! - `must_be_sync`
+//!
+//! **Convert to sync code**. Convert the async code into sync code by
+//! removing all `async move`, `async` and `await` keyword
+//!
+//!
+//! - `sync_impl`
+//!
+//! An sync implementation should on compile on blocking implementation and
+//! must simply disappear when we want async version.
+//!
+//! Although most of the API are almost the same, there definitely come to a
+//! point when the async and sync version should differ greatly. For
+//! example, a MongoDB client may use the same API for async and sync
+//! verison, but the code to actually send reqeust are quite different.
+//!
+//! Here, we can use `sync_impl` to mark a synchronous implementation, and a
+//! sync implementation shoule disappear when we want async version.
+//!
+//! - `async_impl`
+//!
+//! An async implementation should on compile on async implementation and
+//! must simply disappear when we want sync version.
+//!
+//! To avoid having "Send" and "Sync" bounds placed on the async trait
+//! methods, invoke the maybe_async macro as #[async_impl(?Send)].
+//!
+//!
+//! - `test`
+//!
+//! Handy macro to unify async and sync **unit and e2e test** code.
+//!
+//! You can specify the condition to compile to sync test code
+//! and also the conditions to compile to async test code with given test
+//! macro, e.x. `tokio::test`, `async_std::test` and etc. When only sync
+//! condition is specified,the test code only compiles when sync condition
+//! is met.
+//!
+//! ```rust
+//! # #[maybe_async::maybe_async]
+//! # async fn async_fn() -> bool {
+//! # true
+//! # }
+//!
+//! ##[maybe_async::test(
+//! feature="is_sync",
+//! async(
+//! all(not(feature="is_sync"), feature="async_std"),
+//! async_std::test
+//! ),
+//! async(
+//! all(not(feature="is_sync"), feature="tokio"),
+//! tokio::test
+//! )
+//! )]
+//! async fn test_async_fn() {
+//! let res = async_fn().await;
+//! assert_eq!(res, true);
+//! }
+//! ```
+//!
+//! ## What's Under the Hook
+//!
+//! `maybe-async` compiles your code in different way with the `is_sync` feature
+//! gate. It remove all `await` and `async` keywords in your code under
+//! `maybe_async` macro and conditionally compiles codes under `async_impl` and
+//! `sync_impl`.
+//!
+//! Here is an detailed example on what's going on whe the `is_sync` feature
+//! gate set or not.
+//!
+//! ```rust
+//! #[maybe_async::maybe_async(?Send)]
+//! trait A {
+//! async fn async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! struct Foo;
+//!
+//! #[maybe_async::maybe_async(?Send)]
+//! impl A for Foo {
+//! async fn async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! #[maybe_async::maybe_async]
+//! async fn maybe_async_fn() -> Result<(), ()> {
+//! let a = Foo::async_fn_name().await?;
+//!
+//! let b = Foo::sync_fn_name()?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! When `maybe-async` feature gate `is_sync` is **NOT** set, the generated code
+//! is async code:
+//!
+//! ```rust
+//! // Compiled code when `is_sync` is toggled off.
+//! #[async_trait::async_trait(?Send)]
+//! trait A {
+//! async fn maybe_async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! struct Foo;
+//!
+//! #[async_trait::async_trait(?Send)]
+//! impl A for Foo {
+//! async fn maybe_async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! async fn maybe_async_fn() -> Result<(), ()> {
+//! let a = Foo::maybe_async_fn_name().await?;
+//! let b = Foo::sync_fn_name()?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! When `maybe-async` feature gate `is_sync` is set, all async keyword is
+//! ignored and yields a sync version code:
+//!
+//! ```rust
+//! // Compiled code when `is_sync` is toggled on.
+//! trait A {
+//! fn maybe_async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! struct Foo;
+//!
+//! impl A for Foo {
+//! fn maybe_async_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! fn sync_fn_name() -> Result<(), ()> {
+//! Ok(())
+//! }
+//! }
+//!
+//! fn maybe_async_fn() -> Result<(), ()> {
+//! let a = Foo::maybe_async_fn_name()?;
+//! let b = Foo::sync_fn_name()?;
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## Examples
+//!
+//! ### rust client for services
+//!
+//! When implementing rust client for any services, like awz3. The higher level
+//! API of async and sync version is almost the same, such as creating or
+//! deleting a bucket, retrieving an object and etc.
+//!
+//! The example `service_client` is a proof of concept that `maybe_async` can
+//! actually free us from writing almost the same code for sync and async. We
+//! can toggle between a sync AWZ3 client and async one by `is_sync` feature
+//! gate when we add `maybe-async` to dependency.
+//!
+//!
+//! # License
+//! MIT
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+use proc_macro2::{Span, TokenStream as TokenStream2};
+use syn::{
+ parse_macro_input, spanned::Spanned, AttributeArgs, ImplItem, Lit, Meta, NestedMeta, TraitItem,
+};
+
+use quote::quote;
+
+use crate::{parse::Item, visit::AsyncAwaitRemoval};
+
+mod parse;
+mod visit;
+
+fn convert_async(input: &mut Item, send: bool) -> TokenStream2 {
+ if send {
+ match input {
+ Item::Impl(item) => quote!(#[async_trait::async_trait]#item),
+ Item::Trait(item) => quote!(#[async_trait::async_trait]#item),
+ Item::Fn(item) => quote!(#item),
+ Item::Static(item) => quote!(#item),
+ }
+ } else {
+ match input {
+ Item::Impl(item) => quote!(#[async_trait::async_trait(?Send)]#item),
+ Item::Trait(item) => quote!(#[async_trait::async_trait(?Send)]#item),
+ Item::Fn(item) => quote!(#item),
+ Item::Static(item) => quote!(#item),
+ }
+ }
+ .into()
+}
+
+fn convert_sync(input: &mut Item) -> TokenStream2 {
+ match input {
+ Item::Impl(item) => {
+ for inner in &mut item.items {
+ if let ImplItem::Method(ref mut method) = inner {
+ if method.sig.asyncness.is_some() {
+ method.sig.asyncness = None;
+ }
+ }
+ }
+ AsyncAwaitRemoval.remove_async_await(quote!(#item))
+ }
+ Item::Trait(item) => {
+ for inner in &mut item.items {
+ if let TraitItem::Method(ref mut method) = inner {
+ if method.sig.asyncness.is_some() {
+ method.sig.asyncness = None;
+ }
+ }
+ }
+ AsyncAwaitRemoval.remove_async_await(quote!(#item))
+ }
+ Item::Fn(item) => {
+ if item.sig.asyncness.is_some() {
+ item.sig.asyncness = None;
+ }
+ AsyncAwaitRemoval.remove_async_await(quote!(#item))
+ }
+ Item::Static(item) => AsyncAwaitRemoval.remove_async_await(quote!(#item)),
+ }
+ .into()
+}
+
+/// maybe_async attribute macro
+///
+/// Can be applied to trait item, trait impl, functions and struct impls.
+#[proc_macro_attribute]
+pub fn maybe_async(args: TokenStream, input: TokenStream) -> TokenStream {
+ let send = match args.to_string().replace(" ", "").as_str() {
+ "" | "Send" => true,
+ "?Send" => false,
+ _ => {
+ return syn::Error::new(Span::call_site(), "Only accepts `Send` or `?Send`")
+ .to_compile_error()
+ .into();
+ }
+ };
+
+ let mut item = parse_macro_input!(input as Item);
+
+ let token = if cfg!(feature = "is_sync") {
+ convert_sync(&mut item)
+ } else {
+ convert_async(&mut item, send)
+ };
+ token.into()
+}
+
+/// convert marked async code to async code with `async-trait`
+#[proc_macro_attribute]
+pub fn must_be_async(args: TokenStream, input: TokenStream) -> TokenStream {
+ let send = match args.to_string().replace(" ", "").as_str() {
+ "" | "Send" => true,
+ "?Send" => false,
+ _ => {
+ return syn::Error::new(Span::call_site(), "Only accepts `Send` or `?Send`")
+ .to_compile_error()
+ .into();
+ }
+ };
+ let mut item = parse_macro_input!(input as Item);
+ convert_async(&mut item, send).into()
+}
+
+/// convert marked async code to sync code
+#[proc_macro_attribute]
+pub fn must_be_sync(_args: TokenStream, input: TokenStream) -> TokenStream {
+ let mut item = parse_macro_input!(input as Item);
+ convert_sync(&mut item).into()
+}
+
+/// mark sync implementation
+///
+/// only compiled when `is_sync` feature gate is set.
+/// When `is_sync` is not set, marked code is removed.
+#[proc_macro_attribute]
+pub fn sync_impl(_args: TokenStream, input: TokenStream) -> TokenStream {
+ let input = TokenStream2::from(input);
+ let token = if cfg!(feature = "is_sync") {
+ quote!(#input)
+ } else {
+ quote!()
+ };
+ token.into()
+}
+
+/// mark async implementation
+///
+/// only compiled when `is_sync` feature gate is not set.
+/// When `is_sync` is set, marked code is removed.
+#[proc_macro_attribute]
+pub fn async_impl(args: TokenStream, _input: TokenStream) -> TokenStream {
+ let send = match args.to_string().replace(" ", "").as_str() {
+ "" | "Send" => true,
+ "?Send" => false,
+ _ => {
+ return syn::Error::new(Span::call_site(), "Only accepts `Send` or `?Send`")
+ .to_compile_error()
+ .into();
+ }
+ };
+
+ let token = if cfg!(feature = "is_sync") {
+ quote!()
+ } else {
+ let mut item = parse_macro_input!(_input as Item);
+ convert_async(&mut item, send)
+ };
+ token.into()
+}
+
+macro_rules! match_nested_meta_to_str_lit {
+ ($t:expr) => {
+ match $t {
+ NestedMeta::Lit(lit) => {
+ match lit {
+ Lit::Str(s) => {
+ s.value().parse::<TokenStream2>().unwrap()
+ }
+ _ => {
+ return syn::Error::new(lit.span(), "expected meta or string literal").to_compile_error().into();
+ }
+ }
+ }
+ NestedMeta::Meta(meta) => quote!(#meta)
+ }
+ };
+}
+
+/// Handy macro to unify test code of sync and async code
+///
+/// Since the API of both sync and async code are the same,
+/// with only difference that async functions must be awaited.
+/// So it's tedious to write unit sync and async respectively.
+///
+/// This macro helps unify the sync and async unit test code.
+/// Pass the condition to treat test code as sync as the first
+/// argument. And specify the condition when to treat test code
+/// as async and the lib to run async test, e.x. `async-std::test`,
+/// `tokio::test`, or any valid attribute macro.
+///
+/// **ATTENTION**: do not write await inside a assert macro
+///
+/// - Examples
+///
+/// ```rust
+/// #[maybe_async::maybe_async]
+/// async fn async_fn() -> bool {
+/// true
+/// }
+///
+/// #[maybe_async::test(
+/// // when to treat the test code as sync version
+/// feature="is_sync",
+/// // when to run async test
+/// async(all(not(feature="is_sync"), feature="async_std"), async_std::test),
+/// // you can specify multiple conditions for different async runtime
+/// async(all(not(feature="is_sync"), feature="tokio"), tokio::test)
+/// )]
+/// async fn test_async_fn() {
+/// let res = async_fn().await;
+/// assert_eq!(res, true);
+/// }
+///
+/// // Only run test in sync version
+/// #[maybe_async::test(feature = "is_sync")]
+/// async fn test_sync_fn() {
+/// let res = async_fn().await;
+/// assert_eq!(res, true);
+/// }
+/// ```
+///
+/// The above code is transcripted to the following code:
+///
+/// ```rust
+/// # use maybe_async::{must_be_async, must_be_sync, sync_impl};
+/// # #[maybe_async::maybe_async]
+/// # async fn async_fn() -> bool { true }
+///
+/// // convert to sync version when sync condition is met, keep in async version when corresponding
+/// // condition is met
+/// #[cfg_attr(feature = "is_sync", must_be_sync, test)]
+/// #[cfg_attr(
+/// all(not(feature = "is_sync"), feature = "async_std"),
+/// must_be_async,
+/// async_std::test
+/// )]
+/// #[cfg_attr(
+/// all(not(feature = "is_sync"), feature = "tokio"),
+/// must_be_async,
+/// tokio::test
+/// )]
+/// async fn test_async_fn() {
+/// let res = async_fn().await;
+/// assert_eq!(res, true);
+/// }
+///
+/// // force converted to sync function, and only compile on sync condition
+/// #[cfg(feature = "is_sync")]
+/// #[test]
+/// fn test_sync_fn() {
+/// let res = async_fn();
+/// assert_eq!(res, true);
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn test(args: TokenStream, input: TokenStream) -> TokenStream {
+ let attr_args = parse_macro_input!(args as AttributeArgs);
+ let input = TokenStream2::from(input);
+ if attr_args.len() < 1 {
+ return syn::Error::new(
+ Span::call_site(),
+ "Arguments cannot be empty, at least specify the condition for sync code",
+ )
+ .to_compile_error()
+ .into();
+ }
+
+ // The first attributes indicates sync condition
+ let sync_cond = match_nested_meta_to_str_lit!(attr_args.first().unwrap());
+ let mut ts = quote!(#[cfg_attr(#sync_cond, maybe_async::must_be_sync, test)]);
+
+ // The rest attributes indicates async condition and async test macro
+ // only accepts in the forms of `async(cond, test_macro)`, but `cond` and
+ // `test_macro` can be either meta attributes or string literal
+ let mut async_token = Vec::new();
+ let mut async_conditions = Vec::new();
+ for async_meta in attr_args.into_iter().skip(1) {
+ match async_meta {
+ NestedMeta::Meta(meta) => match meta {
+ Meta::List(list) => {
+ let name = list.path.segments[0].ident.to_string();
+ if name.ne("async") {
+ return syn::Error::new(
+ list.path.span(),
+ format!("Unknown path: `{}`, must be `async`", name),
+ )
+ .to_compile_error()
+ .into();
+ }
+ if list.nested.len() == 2 {
+ let async_cond =
+ match_nested_meta_to_str_lit!(list.nested.first().unwrap());
+ let async_test = match_nested_meta_to_str_lit!(list.nested.last().unwrap());
+ let attr = quote!(
+ #[cfg_attr(#async_cond, maybe_async::must_be_async, #async_test)]
+ );
+ async_conditions.push(async_cond);
+ async_token.push(attr);
+ } else {
+ let msg = format!(
+ "Must pass two metas or string literals like `async(condition, \
+ async_test_macro)`, you passed {} metas.",
+ list.nested.len()
+ );
+ return syn::Error::new(list.span(), msg).to_compile_error().into();
+ }
+ }
+ _ => {
+ return syn::Error::new(
+ meta.span(),
+ "Must be list of metas like: `async(condition, async_test_macro)`",
+ )
+ .to_compile_error()
+ .into();
+ }
+ },
+ NestedMeta::Lit(lit) => {
+ return syn::Error::new(
+ lit.span(),
+ "Must be list of metas like: `async(condition, async_test_macro)`",
+ )
+ .to_compile_error()
+ .into();
+ }
+ };
+ }
+
+ async_token.into_iter().for_each(|t| ts.extend(t));
+ ts.extend(quote!( #input ));
+ if !async_conditions.is_empty() {
+ quote! {
+ #[cfg(any(#sync_cond, #(#async_conditions),*))]
+ #ts
+ }
+ } else {
+ quote! {
+ #[cfg(#sync_cond)]
+ #ts
+ }
+ }
+ .into()
+}
diff --git a/vendor/maybe-async/src/parse.rs b/vendor/maybe-async/src/parse.rs
new file mode 100644
index 000000000..b5a8cf903
--- /dev/null
+++ b/vendor/maybe-async/src/parse.rs
@@ -0,0 +1,49 @@
+use proc_macro2::Span;
+use syn::{
+ parse::{discouraged::Speculative, Parse, ParseStream, Result},
+ Attribute, Error, ItemFn, ItemImpl, ItemStatic, ItemTrait,
+};
+
+pub enum Item {
+ Trait(ItemTrait),
+ Impl(ItemImpl),
+ Fn(ItemFn),
+ Static(ItemStatic),
+}
+
+macro_rules! fork {
+ ($fork:ident = $input:ident) => {{
+ $fork = $input.fork();
+ &$fork
+ }};
+}
+
+impl Parse for Item {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let attrs = input.call(Attribute::parse_outer)?;
+ let mut fork;
+ let item = if let Some(mut item) = fork!(fork = input).parse::<ItemImpl>().ok() {
+ if item.trait_.is_none() {
+ return Err(Error::new(Span::call_site(), "expected a trait impl"));
+ }
+ item.attrs = attrs;
+ Item::Impl(item)
+ } else if let Some(mut item) = fork!(fork = input).parse::<ItemTrait>().ok() {
+ item.attrs = attrs;
+ Item::Trait(item)
+ } else if let Some(mut item) = fork!(fork = input).parse::<ItemFn>().ok() {
+ item.attrs = attrs;
+ Item::Fn(item)
+ } else if let Some(mut item) = fork!(fork = input).parse::<ItemStatic>().ok() {
+ item.attrs = attrs;
+ Item::Static(item)
+ } else {
+ return Err(Error::new(
+ Span::call_site(),
+ "expected trait impl, trait or fn",
+ ));
+ };
+ input.advance_to(&fork);
+ Ok(item)
+ }
+}
diff --git a/vendor/maybe-async/src/visit.rs b/vendor/maybe-async/src/visit.rs
new file mode 100644
index 000000000..e33c24273
--- /dev/null
+++ b/vendor/maybe-async/src/visit.rs
@@ -0,0 +1,199 @@
+use std::iter::FromIterator;
+
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::{
+ parse_quote,
+ punctuated::Punctuated,
+ visit_mut::{self, visit_item_mut, visit_path_segment_mut, VisitMut},
+ Expr, ExprBlock, File, GenericArgument, GenericParam, Item, PathArguments, PathSegment, Type,
+ TypeParamBound, WherePredicate,
+};
+
+pub struct ReplaceGenericType<'a> {
+ generic_type: &'a str,
+ arg_type: &'a PathSegment,
+}
+
+impl<'a> ReplaceGenericType<'a> {
+ pub fn new(generic_type: &'a str, arg_type: &'a PathSegment) -> Self {
+ Self {
+ generic_type,
+ arg_type,
+ }
+ }
+
+ pub fn replace_generic_type(item: &mut Item, generic_type: &'a str, arg_type: &'a PathSegment) {
+ let mut s = Self::new(generic_type, arg_type);
+ s.visit_item_mut(item);
+ }
+}
+
+impl<'a> VisitMut for ReplaceGenericType<'a> {
+ fn visit_item_mut(&mut self, i: &mut Item) {
+ if let Item::Fn(item_fn) = i {
+ // remove generic type from generics <T, F>
+ let args = item_fn
+ .sig
+ .generics
+ .params
+ .iter()
+ .filter_map(|param| {
+ if let GenericParam::Type(type_param) = &param {
+ if type_param.ident.to_string().eq(self.generic_type) {
+ None
+ } else {
+ Some(param)
+ }
+ } else {
+ Some(param)
+ }
+ })
+ .collect::<Vec<_>>();
+ item_fn.sig.generics.params =
+ Punctuated::from_iter(args.into_iter().map(|p| p.clone()).collect::<Vec<_>>());
+
+ // remove generic type from where clause
+ if let Some(where_clause) = &mut item_fn.sig.generics.where_clause {
+ let new_where_clause = where_clause
+ .predicates
+ .iter()
+ .filter_map(|predicate| {
+ if let WherePredicate::Type(predicate_type) = predicate {
+ if let Type::Path(p) = &predicate_type.bounded_ty {
+ if p.path.segments[0].ident.to_string().eq(self.generic_type) {
+ None
+ } else {
+ Some(predicate)
+ }
+ } else {
+ Some(predicate)
+ }
+ } else {
+ Some(predicate)
+ }
+ })
+ .collect::<Vec<_>>();
+
+ where_clause.predicates = Punctuated::from_iter(
+ new_where_clause
+ .into_iter()
+ .map(|c| c.clone())
+ .collect::<Vec<_>>(),
+ );
+ };
+ }
+ visit_item_mut(self, i)
+ }
+ fn visit_path_segment_mut(&mut self, i: &mut PathSegment) {
+ // replace generic type with target type
+ if i.ident.to_string().eq(&self.generic_type) {
+ *i = self.arg_type.clone();
+ }
+ visit_path_segment_mut(self, i);
+ }
+}
+
+pub struct AsyncAwaitRemoval;
+
+impl AsyncAwaitRemoval {
+ pub fn remove_async_await(&mut self, item: TokenStream) -> TokenStream {
+ let mut syntax_tree: File = syn::parse(item.into()).unwrap();
+ self.visit_file_mut(&mut syntax_tree);
+ quote!(#syntax_tree)
+ }
+}
+
+impl VisitMut for AsyncAwaitRemoval {
+ fn visit_expr_mut(&mut self, node: &mut Expr) {
+ // Delegate to the default impl to visit nested expressions.
+ visit_mut::visit_expr_mut(self, node);
+
+ match node {
+ Expr::Await(expr) => *node = (*expr.base).clone(),
+
+ Expr::Async(expr) => {
+ let inner = &expr.block;
+ let sync_expr = if inner.stmts.len() == 1 {
+ // remove useless braces when there is only one statement
+ let stmt = &inner.stmts.get(0).unwrap();
+ // convert statement to Expr
+ parse_quote!(#stmt)
+ } else {
+ Expr::Block(ExprBlock {
+ attrs: expr.attrs.clone(),
+ block: inner.clone(),
+ label: None,
+ })
+ };
+ *node = sync_expr;
+ }
+ _ => {}
+ }
+ }
+
+ fn visit_item_mut(&mut self, i: &mut Item) {
+ // find generic parameter of Future and replace it with its Output type
+ if let Item::Fn(item_fn) = i {
+ let mut inputs: Vec<(String, PathSegment)> = vec![];
+
+ // generic params: <T:Future<Output=()>, F>
+ for param in &item_fn.sig.generics.params {
+ // generic param: T:Future<Output=()>
+ if let GenericParam::Type(type_param) = param {
+ let generic_type_name = type_param.ident.to_string();
+
+ // bound: Future<Output=()>
+ for bound in &type_param.bounds {
+ inputs.extend(search_trait_bound(&generic_type_name, bound));
+ }
+ }
+ }
+
+ if let Some(where_clause) = &item_fn.sig.generics.where_clause {
+ for predicate in &where_clause.predicates {
+ if let WherePredicate::Type(predicate_type) = predicate {
+ let generic_type_name = if let Type::Path(p) = &predicate_type.bounded_ty {
+ p.path.segments[0].ident.to_string()
+ } else {
+ panic!("Please submit an issue");
+ };
+
+ for bound in &predicate_type.bounds {
+ inputs.extend(search_trait_bound(&generic_type_name, bound));
+ }
+ }
+ }
+ }
+
+ for (generic_type_name, path_seg) in &inputs {
+ ReplaceGenericType::replace_generic_type(i, generic_type_name, path_seg);
+ }
+ }
+ visit_item_mut(self, i);
+ }
+}
+
+fn search_trait_bound(
+ generic_type_name: &str,
+ bound: &TypeParamBound,
+) -> Vec<(String, PathSegment)> {
+ let mut inputs = vec![];
+
+ if let TypeParamBound::Trait(trait_bound) = bound {
+ let segment = &trait_bound.path.segments[trait_bound.path.segments.len() - 1];
+ let name = segment.ident.to_string();
+ if name.eq("Future") {
+ // match Future<Output=Type>
+ if let PathArguments::AngleBracketed(args) = &segment.arguments {
+ // binding: Output=Type
+ if let GenericArgument::Binding(binding) = &args.args[0] {
+ if let Type::Path(p) = &binding.ty {
+ inputs.push((generic_type_name.to_owned(), p.path.segments[0].clone()));
+ }
+ }
+ }
+ }
+ }
+ inputs
+}
diff --git a/vendor/maybe-async/tests/test.rs b/vendor/maybe-async/tests/test.rs
new file mode 100644
index 000000000..4062e39dc
--- /dev/null
+++ b/vendor/maybe-async/tests/test.rs
@@ -0,0 +1,15 @@
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.pass("tests/ui/01-maybe-async.rs");
+ t.pass("tests/ui/02-must-be-async.rs");
+ t.pass("tests/ui/03-must-be-sync.rs");
+ t.pass("tests/ui/04-unit-test-util.rs");
+ t.pass("tests/ui/05-replace-future-generic-type-with-output.rs");
+ t.pass("tests/ui/06-sync_impl_async_impl.rs");
+
+ t.compile_fail("tests/ui/test_fail/01-empty-test.rs");
+ t.compile_fail("tests/ui/test_fail/02-unknown-path.rs");
+ t.compile_fail("tests/ui/test_fail/03-async-gt2.rs");
+ t.compile_fail("tests/ui/test_fail/04-bad-sync-cond.rs");
+}
diff --git a/vendor/maybe-async/tests/ui/01-maybe-async.rs b/vendor/maybe-async/tests/ui/01-maybe-async.rs
new file mode 100644
index 000000000..33b8248e5
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/01-maybe-async.rs
@@ -0,0 +1,81 @@
+#![allow(dead_code)]
+
+use maybe_async::maybe_async;
+
+#[maybe_async(Send)]
+trait Trait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async(?Send)]
+pub trait PubTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async]
+pub(crate) trait PubCrateTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async]
+async fn async_fn() {}
+
+#[maybe_async]
+pub async fn pub_async_fn() {}
+
+#[maybe_async]
+pub(crate) async fn pub_crate_async_fn() {}
+
+#[maybe_async]
+unsafe fn unsafe_fn() {}
+
+struct Struct;
+
+#[maybe_async]
+impl Trait for Struct {
+ fn sync_fn() {}
+
+ async fn declare_async(&self) {}
+
+ async fn async_fn(&self) {
+ async { self.declare_async().await }.await
+ }
+}
+
+#[cfg(feature = "is_sync")]
+fn main() -> std::result::Result<(), ()> {
+ let s = Struct;
+ s.declare_async();
+ s.async_fn();
+ async_fn();
+ pub_async_fn();
+ Ok(())
+}
+
+#[cfg(not(feature = "is_sync"))]
+#[async_std::main]
+async fn main() {
+ let s = Struct;
+ s.declare_async().await;
+ s.async_fn().await;
+ async_fn().await;
+ pub_async_fn().await;
+}
diff --git a/vendor/maybe-async/tests/ui/02-must-be-async.rs b/vendor/maybe-async/tests/ui/02-must-be-async.rs
new file mode 100644
index 000000000..cfe2285b8
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/02-must-be-async.rs
@@ -0,0 +1,96 @@
+#![allow(dead_code)]
+
+#[maybe_async::maybe_async]
+trait Trait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async::maybe_async(?Send)]
+trait NotSendTrait {
+ async fn declare_async_not_send(&self);
+
+ async fn async_fn_not_send(&self) {
+ self.declare_async_not_send().await
+ }
+}
+
+#[maybe_async::maybe_async]
+pub trait PubTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async::maybe_async]
+pub(crate) trait PubCrateTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::must_be_async]
+async fn async_fn() {}
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::must_be_async]
+pub async fn pub_async_fn() {}
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::maybe_async]
+pub(crate) async fn pub_crate_async_fn() {}
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::maybe_async]
+unsafe fn unsafe_fn() {}
+
+struct Struct;
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::must_be_async]
+impl Trait for Struct {
+ fn sync_fn() {}
+
+ async fn declare_async(&self) {}
+
+ async fn async_fn(&self) {
+ async { self.declare_async().await }.await
+ }
+}
+
+#[cfg(not(feature = "is_sync"))]
+#[maybe_async::must_be_async(?Send)]
+impl NotSendTrait for Struct {
+ async fn declare_async_not_send(&self) {}
+
+ async fn async_fn_not_send(&self) {
+ async { self.declare_async_not_send().await }.await
+ }
+}
+
+#[cfg(feature = "is_sync")]
+fn main() {}
+
+#[cfg(not(feature = "is_sync"))]
+#[async_std::main]
+async fn main() {
+ let s = Struct;
+ s.declare_async().await;
+ s.async_fn().await;
+ async_fn().await;
+ pub_async_fn().await;
+}
diff --git a/vendor/maybe-async/tests/ui/03-must-be-sync.rs b/vendor/maybe-async/tests/ui/03-must-be-sync.rs
new file mode 100644
index 000000000..94fa30fc6
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/03-must-be-sync.rs
@@ -0,0 +1,74 @@
+#![allow(dead_code)]
+
+#[maybe_async::maybe_async]
+trait Trait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async::maybe_async]
+pub trait PubTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async::maybe_async]
+pub(crate) trait PubCrateTrait {
+ fn sync_fn() {}
+
+ async fn declare_async(&self);
+
+ async fn async_fn(&self) {
+ self.declare_async().await
+ }
+}
+
+#[maybe_async::maybe_async]
+async fn async_fn() {}
+
+#[maybe_async::maybe_async]
+pub async fn pub_async_fn() {}
+
+#[maybe_async::maybe_async]
+pub(crate) async fn pub_crate_async_fn() {}
+
+#[maybe_async::maybe_async]
+unsafe fn unsafe_fn() {}
+
+struct Struct;
+
+#[cfg(feature = "is_sync")]
+#[maybe_async::must_be_sync]
+impl Trait for Struct {
+ fn sync_fn() {}
+
+ async fn declare_async(&self) {}
+
+ async fn async_fn(&self) {
+ async { self.declare_async().await }.await
+ }
+}
+
+#[cfg(feature = "is_sync")]
+fn main() -> std::result::Result<(), ()> {
+ let s = Struct;
+ s.declare_async();
+ s.async_fn();
+ async_fn();
+ pub_async_fn();
+ Ok(())
+}
+
+#[cfg(not(feature = "is_sync"))]
+#[async_std::main]
+async fn main() {}
diff --git a/vendor/maybe-async/tests/ui/04-unit-test-util.rs b/vendor/maybe-async/tests/ui/04-unit-test-util.rs
new file mode 100644
index 000000000..4642e1f84
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/04-unit-test-util.rs
@@ -0,0 +1,38 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+#[maybe_async::test(
+feature = "is_sync",
+async(all(not(feature="is_sync"), feature = "async_std"), async_std::test),
+async(all(not(feature="is_sync"), feature = "tokio"), tokio::test)
+)]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test(feature = "is_sync", async(not(feature = "is_sync"), async_std::test))]
+async fn test_async_fn2() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test("feature=\"is_sync\"", async(not(feature = "is_sync"), async_std::test))]
+async fn test_async_fn3() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test(feature = "is_sync", async("not(feature = \"is_sync\")", "async_std::test"))]
+async fn test_async_fn4() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+fn main() {
+
+}
diff --git a/vendor/maybe-async/tests/ui/05-replace-future-generic-type-with-output.rs b/vendor/maybe-async/tests/ui/05-replace-future-generic-type-with-output.rs
new file mode 100644
index 000000000..241058069
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/05-replace-future-generic-type-with-output.rs
@@ -0,0 +1,34 @@
+#![allow(unused_imports)]
+use std::future::Future;
+
+#[maybe_async::maybe_async]
+pub async fn with_fn<T, F: Sync + std::future::Future<Output = Result<(), ()>>>(
+ test: T,
+) -> Result<(), ()>
+ where
+ T: FnOnce() -> F,
+{
+ test().await
+}
+
+#[maybe_async::maybe_async]
+pub async fn with_fn_where<T, F>(test: T) -> Result<(), ()>
+ where
+ T: FnOnce() -> F,
+ F: Sync + Future<Output = Result<(), ()>>,
+{
+ test().await
+}
+
+#[maybe_async::sync_impl]
+fn main() {
+ with_fn(|| Ok(())).unwrap();
+ with_fn_where(|| Ok(())).unwrap();
+}
+
+#[maybe_async::async_impl]
+#[tokio::main]
+async fn main() {
+ with_fn(|| async { Ok(()) }).await.unwrap();
+ with_fn_where(|| async { Ok(()) }).await.unwrap();
+}
diff --git a/vendor/maybe-async/tests/ui/06-sync_impl_async_impl.rs b/vendor/maybe-async/tests/ui/06-sync_impl_async_impl.rs
new file mode 100644
index 000000000..68605faa0
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/06-sync_impl_async_impl.rs
@@ -0,0 +1,44 @@
+#![allow(dead_code, unused_variables)]
+
+/// InnerClient differ a lot between sync and async.
+#[maybe_async::maybe_async]
+trait Trait {
+ async fn maybe_async_fn();
+}
+
+/// The higher level API for end user.
+pub struct Struct;
+
+/// Synchronous implementation, only compiles when `is_sync` feature is off.
+/// Else the compiler will complain that *request is defined multiple times* and
+/// blabla.
+#[maybe_async::sync_impl]
+impl Trait for Struct {
+ fn maybe_async_fn() { }
+}
+
+/// Asynchronous implementation, only compiles when `is_sync` feature is off.
+#[maybe_async::async_impl]
+impl Trait for Struct {
+ async fn maybe_async_fn() { }
+}
+
+impl Struct {
+ #[maybe_async::maybe_async]
+ async fn another_maybe_async_fn() {
+ Self::maybe_async_fn().await
+ // When `is_sync` is toggle on, this block will compiles to:
+ // Self::maybe_async_fn()
+ }
+}
+
+#[maybe_async::sync_impl]
+fn main() {
+ let _ = Struct::another_maybe_async_fn();
+}
+
+#[maybe_async::async_impl]
+#[tokio::main]
+async fn main() {
+ let _ = Struct::another_maybe_async_fn().await;
+}
diff --git a/vendor/maybe-async/tests/ui/test_fail/01-empty-test.rs b/vendor/maybe-async/tests/ui/test_fail/01-empty-test.rs
new file mode 100644
index 000000000..f409e7334
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/01-empty-test.rs
@@ -0,0 +1,17 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+// at least one sync condition should be specified
+#[maybe_async::test()]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+fn main() {
+
+}
diff --git a/vendor/maybe-async/tests/ui/test_fail/01-empty-test.stderr b/vendor/maybe-async/tests/ui/test_fail/01-empty-test.stderr
new file mode 100644
index 000000000..b90d9ee35
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/01-empty-test.stderr
@@ -0,0 +1,7 @@
+error: Arguments cannot be empty, at least specify the condition for sync code
+ --> tests/ui/test_fail/01-empty-test.rs:9:1
+ |
+9 | #[maybe_async::test()]
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the attribute macro `maybe_async::test` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.rs b/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.rs
new file mode 100644
index 000000000..7b79bd1f2
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.rs
@@ -0,0 +1,17 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+// should only accept `async`
+#[maybe_async::test(feature="is_sync", unknown(not(feature="is_sync"), async_std::test))]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+fn main() {
+
+}
diff --git a/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.stderr b/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.stderr
new file mode 100644
index 000000000..6a603c01d
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/02-unknown-path.stderr
@@ -0,0 +1,5 @@
+error: Unknown path: `unknown`, must be `async`
+ --> tests/ui/test_fail/02-unknown-path.rs:9:40
+ |
+9 | #[maybe_async::test(feature="is_sync", unknown(not(feature="is_sync"), async_std::test))]
+ | ^^^^^^^
diff --git a/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.rs b/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.rs
new file mode 100644
index 000000000..f7313bd52
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.rs
@@ -0,0 +1,16 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+#[maybe_async::test(feature="is_sync", async(feature="async", async_std::test, added))]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+fn main() {
+
+}
diff --git a/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.stderr b/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.stderr
new file mode 100644
index 000000000..8c051da85
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/03-async-gt2.stderr
@@ -0,0 +1,5 @@
+error: Must pass two metas or string literals like `async(condition, async_test_macro)`, you passed 3 metas.
+ --> tests/ui/test_fail/03-async-gt2.rs:8:40
+ |
+8 | #[maybe_async::test(feature="is_sync", async(feature="async", async_std::test, added))]
+ | ^^^^^
diff --git a/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.rs b/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.rs
new file mode 100644
index 000000000..f5ad658a4
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.rs
@@ -0,0 +1,17 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+// bad sync condition
+#[maybe_async::test(unknown(feature="async", async_std::test))]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+fn main() {
+
+} \ No newline at end of file
diff --git a/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.stderr b/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.stderr
new file mode 100644
index 000000000..97294ffcc
--- /dev/null
+++ b/vendor/maybe-async/tests/ui/test_fail/04-bad-sync-cond.stderr
@@ -0,0 +1,5 @@
+error[E0537]: invalid predicate `unknown`
+ --> tests/ui/test_fail/04-bad-sync-cond.rs:9:21
+ |
+9 | #[maybe_async::test(unknown(feature="async", async_std::test))]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/vendor/maybe-async/tests/unit-test-util.rs b/vendor/maybe-async/tests/unit-test-util.rs
new file mode 100644
index 000000000..486fa6e1b
--- /dev/null
+++ b/vendor/maybe-async/tests/unit-test-util.rs
@@ -0,0 +1,30 @@
+use maybe_async::maybe_async;
+
+#[maybe_async]
+async fn async_fn() -> bool {
+ true
+}
+
+#[maybe_async::test(feature = "is_sync", async(not(feature = "is_sync"), async_std::test))]
+async fn test_async_fn() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test(feature = "is_sync", async(not(feature = "is_sync"), tokio::test))]
+async fn test_async_fn2() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test(feature = "is_sync")]
+async fn test_async_fn3() {
+ let res = async_fn().await;
+ assert_eq!(res, true);
+}
+
+#[maybe_async::test(feature = "is_sync")]
+async fn test_sync_fn() {
+ let res = async_fn();
+ assert_eq!(res, true);
+}