diff options
Diffstat (limited to 'vendor/maybe-async')
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) = ¶m { + 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); +} |