1use crate::{error::ServerFnError, request::ClientReq, response::ClientRes};
2use std::{future::Future, sync::OnceLock};
3
4static ROOT_URL: OnceLock<&'static str> = OnceLock::new();
5
6pub fn set_server_url(url: &'static str) {
10 ROOT_URL.set(url).unwrap();
11}
12
13pub fn get_server_url() -> &'static str {
15 ROOT_URL.get().copied().unwrap_or("")
16}
17
18pub trait Client<CustErr> {
25 type Request: ClientReq<CustErr> + Send;
27 type Response: ClientRes<CustErr> + Send;
29
30 fn send(
32 req: Self::Request,
33 ) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>> + Send;
34}
35
36#[cfg(feature = "browser")]
37pub mod browser {
39 use super::Client;
40 use crate::{
41 error::ServerFnError,
42 request::browser::{BrowserRequest, RequestInner},
43 response::browser::BrowserResponse,
44 };
45 use send_wrapper::SendWrapper;
46 use std::future::Future;
47
48 pub struct BrowserClient;
50
51 impl<CustErr> Client<CustErr> for BrowserClient {
52 type Request = BrowserRequest;
53 type Response = BrowserResponse;
54
55 fn send(
56 req: Self::Request,
57 ) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>>
58 + Send {
59 SendWrapper::new(async move {
60 let req = req.0.take();
61 let RequestInner {
62 request,
63 mut abort_ctrl,
64 } = req;
65 let res = request
66 .send()
67 .await
68 .map(|res| BrowserResponse(SendWrapper::new(res)))
69 .map_err(|e| ServerFnError::Request(e.to_string()));
70
71 if let Some(ctrl) = abort_ctrl.as_mut() {
74 ctrl.prevent_cancellation();
75 }
76 res
77 })
78 }
79 }
80}
81
82#[cfg(feature = "reqwest")]
83pub mod reqwest {
85 use super::Client;
86 use crate::{error::ServerFnError, request::reqwest::CLIENT};
87 use futures::TryFutureExt;
88 use reqwest::{Request, Response};
89 use std::future::Future;
90
91 pub struct ReqwestClient;
93
94 impl<CustErr> Client<CustErr> for ReqwestClient {
95 type Request = Request;
96 type Response = Response;
97
98 fn send(
99 req: Self::Request,
100 ) -> impl Future<Output = Result<Self::Response, ServerFnError<CustErr>>>
101 + Send {
102 CLIENT
103 .execute(req)
104 .map_err(|e| ServerFnError::Request(e.to_string()))
105 }
106 }
107}