use crate::{error::ServerFnError, request::ClientReq, response::ClientRes};
use std::{future::Future, sync::OnceLock};
static ROOT_URL: OnceLock<&'static str> = OnceLock::new();
pub fn set_server_url(url: &'static str) {
ROOT_URL.set(url).unwrap();
}
pub fn get_server_url() -> &'static str {
ROOT_URL.get().copied().unwrap_or("")
}
pub trait Client<CustErr> {
type Request: ClientReq<CustErr> + Send;
type Response: ClientRes<CustErr> + Send;
fn send(
req: Self::Request,
) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>> + Send;
}
#[cfg(feature = "browser")]
pub mod browser {
use super::Client;
use crate::{
error::ServerFnError,
request::browser::{BrowserRequest, RequestInner},
response::browser::BrowserResponse,
};
use send_wrapper::SendWrapper;
use std::future::Future;
pub struct BrowserClient;
impl<CustErr> Client<CustErr> for BrowserClient {
type Request = BrowserRequest;
type Response = BrowserResponse;
fn send(
req: Self::Request,
) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>>
+ Send {
SendWrapper::new(async move {
let req = req.0.take();
let RequestInner {
request,
mut abort_ctrl,
} = req;
let res = request
.send()
.await
.map(|res| BrowserResponse(SendWrapper::new(res)))
.map_err(|e| ServerFnError::Request(e.to_string()));
if let Some(ctrl) = abort_ctrl.as_mut() {
ctrl.prevent_cancellation();
}
res
})
}
}
}
#[cfg(feature = "reqwest")]
pub mod reqwest {
use super::Client;
use crate::{error::ServerFnError, request::reqwest::CLIENT};
use futures::TryFutureExt;
use reqwest::{Request, Response};
use std::future::Future;
pub struct ReqwestClient;
impl<CustErr> Client<CustErr> for ReqwestClient {
type Request = Request;
type Response = Response;
fn send(
req: Self::Request,
) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>>
+ Send {
CLIENT
.execute(req)
.map_err(|e| ServerFnError::Request(e.to_string()))
}
}
}