1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
//!Client runtime //! //!Due to limitation of `async fn`, the global client is provided by means of macro //. //!The macro defines global client in current scope, alongside companion `Request` wrapper and `GlobalRequest` trait. //!Refer to macro documentation for details. //! //!## Usage //! //!```rust,no_run //!use yukikaze::client::Request; //! //!mod generated { //! use yukikaze::client; //! use core::time; //! //! pub struct TimeoutCfg; //! //! impl client::config::Config for TimeoutCfg { //! type Connector = client::config::DefaultConnector; //! type Timer = client::config::DefaultTimer; //! //! fn timeout() -> time::Duration { //! time::Duration::from_millis(50) //! } //! } //! //! yukikaze::declare_global_client!(TimeoutCfg); //!} //! //!use generated::{GlobalRequest}; //! //!async fn google() { //! let res = Request::get("https://google.com").expect("To create get request") //! .empty() //! .global() //! .send(); //! let result = yukikaze::matsu!(res).expect("To get without timeout") //! .expect("Successful response"); //! assert!(result.is_success()); //!} //!``` #[macro_export] ///Declares global client for use. /// ///If no argument is specified, uses [`DefaultCfg`](client/config/struct.DefaultCfg.html) ///Otherwise you must provide accessible type of unit struct that implements [`Config`](client/config/trait.Config.html) /// ///Creates following: /// ///- `GLOBAL_CLIENT` which is initialized using `lazy_static` ///- `Request` which uses `GLOBAL_CLIENT` and wraps `yukikaze::client::Request` ///- Creates and defines trait `GlobalRequest` for generated `Request`. /// ///See example of [generated](rt/client/generated/struct.Request.html) /// ///See [usage](rt/client/index.html) macro_rules! declare_global_client { () => { use $crate::client::config::DefaultCfg; $crate::declare_global_client!(DefaultCfg); }; ($config:ty) => { $crate::lazy_static::lazy_static! { ///Global client instance pub static ref GLOBAL_CLIENT: $crate::client::Client::<$config> = $crate::client::Client::<$config>::new(); } ///Global request /// ///Implements `Deref` and `DerefMut` to access regular yukikaze's request. pub struct Request(pub $crate::client::Request); impl core::ops::Deref for Request { type Target = $crate::client::Request; fn deref(&self) -> &Self::Target { &self.0 } } impl core::ops::DerefMut for Request { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } ///Helper trait to convert request to global request. pub trait GlobalRequest { ///Type of global request type Result; ///Wraps request into global request fn global(self) -> Self::Result; } impl GlobalRequest for $crate::client::Request { type Result = Request; fn global(self) -> Self::Result { Request(self) } } use $crate::client::RequestResult; impl Request { #[inline(always)] ///Sends request, and returns future that resolves to response pub fn request(self) -> impl core::future::Future<Output=RequestResult> { GLOBAL_CLIENT.request(self.0) } #[inline(always)] ///Sends request and returns response. Timed version. /// ///On timeout error it returns `async_timer::Expired` as `Error` ///`Expired` implements `Future` that can be used to re-spawn ongoing request again. /// ///If request resolves in time returns `Result<response::Response, hyper::Error>` as `Ok` ///variant. pub fn send(self) -> impl core::future::Future<Output=Result<RequestResult, $crate::async_timer::Expired<impl core::future::Future<Output=RequestResult>, impl $crate::async_timer::Oneshot>>> { GLOBAL_CLIENT.send(self.0) } #[inline(always)] ///Sends request and returns response, while handling redirects. Timed version. /// ///On timeout error it returns `async_timer::Expired` as `Error` ///`Expired` implements `Future` that can be used to re-spawn ongoing request again. /// ///If request resolves in time returns `Result<response::Response, hyper::Error>` as `Ok` ///variant. pub fn send_redirect(self) -> impl core::future::Future<Output=Result<RequestResult, $crate::async_timer::Expired<impl core::future::Future<Output=RequestResult> + 'static, impl $crate::async_timer::Oneshot>>> { GLOBAL_CLIENT.send_redirect(self.0) } #[inline(always)] ///Sends request and returns response, while handling redirects. pub fn redirect_request(self) -> impl core::future::Future<Output=RequestResult> { GLOBAL_CLIENT.redirect_request(self.0) } } }; } #[cfg(feature = "docs")] ///Example of generated global client pub mod generated { declare_global_client!(); }