summaryrefslogtreecommitdiffstats
path: root/vendor/maybe-async/examples
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maybe-async/examples')
-rw-r--r--vendor/maybe-async/examples/service_client.rs75
1 files changed, 75 insertions, 0 deletions
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;
+}