use std::fmt;
use parking_lot::RwLock;
use crate::http::{uri::Origin, Method};
use crate::listener::Endpoint;
use crate::local::asynchronous::{LocalRequest, LocalResponse};
use crate::{Error, Ignite, Orbit, Phase, Rocket};
pub struct Client {
rocket: Rocket<Orbit>,
cookies: RwLock<cookie::CookieJar>,
pub(super) tracked: bool,
}
impl Client {
pub(crate) async fn _new<P: Phase>(
rocket: Rocket<P>,
tracked: bool,
secure: bool,
) -> Result<Client, Error> {
let mut endpoint = Endpoint::new("local client");
if secure {
endpoint = endpoint.assume_tls();
}
let rocket = rocket.local_launch(endpoint).await?;
let cookies = RwLock::new(cookie::CookieJar::new());
Ok(Client {
rocket,
cookies,
tracked,
})
}
#[doc(hidden)]
pub fn _test<T, F>(f: F) -> T
where
F: FnOnce(&Self, LocalRequest<'_>, LocalResponse<'_>) -> T + Send,
{
crate::async_test(async {
let client = Client::debug(crate::build()).await.unwrap();
let request = client.get("/");
let response = request.clone().dispatch().await;
f(&client, request, response)
})
}
#[inline(always)]
pub(crate) fn _rocket(&self) -> &Rocket<Orbit> {
&self.rocket
}
#[inline(always)]
pub(crate) fn _with_raw_cookies<F, T>(&self, f: F) -> T
where
F: FnOnce(&cookie::CookieJar) -> T,
{
f(&self.cookies.read())
}
#[inline(always)]
pub(crate) fn _with_raw_cookies_mut<F, T>(&self, f: F) -> T
where
F: FnOnce(&mut cookie::CookieJar) -> T,
{
f(&mut self.cookies.write())
}
#[inline(always)]
fn _req<'c, 'u: 'c, U>(&'c self, method: Method, uri: U) -> LocalRequest<'c>
where
U: TryInto<Origin<'u>> + fmt::Display,
{
LocalRequest::new(self, method, uri)
}
pub(crate) async fn _terminate(self) -> Rocket<Ignite> {
let rocket = self.rocket;
rocket.shutdown().notify();
rocket.fairings.handle_shutdown(&rocket).await;
rocket.deorbit()
}
pub_client_impl!("use rkt::local::asynchronous::Client;" @async await);
}
impl std::fmt::Debug for Client {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self._rocket().fmt(f)
}
}
#[cfg(test)]
mod test {
#[test]
fn test_local_client_impl_send_sync() {
fn assert_sync_send<T: Sync + Send>() {}
assert_sync_send::<super::Client>();
}
}