77 lines
2.7 KiB
Rust
77 lines
2.7 KiB
Rust
#![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.
|
|
///
|
|
/// Use native async function in trait
|
|
#[maybe_async::maybe_async(AFIT)]
|
|
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(AFIT)]
|
|
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;
|
|
}
|