diff options
Diffstat (limited to 'vendor/maybe-async/examples')
-rw-r--r-- | vendor/maybe-async/examples/service_client.rs | 75 |
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; +} |