rocket/local/asynchronous/
client.rs1use std::fmt;
2
3use parking_lot::RwLock;
4
5use crate::{Rocket, Phase, Orbit, Ignite, Error};
6use crate::local::asynchronous::{LocalRequest, LocalResponse};
7use crate::http::{Method, uri::Origin};
8use crate::listener::Endpoint;
9
10pub struct Client {
51 rocket: Rocket<Orbit>,
52 cookies: RwLock<cookie::CookieJar>,
53 pub(in super) tracked: bool,
54}
55
56impl Client {
57 pub(crate) async fn _new<P: Phase>(
58 rocket: Rocket<P>,
59 tracked: bool,
60 secure: bool,
61 ) -> Result<Client, Error> {
62 let mut endpoint = Endpoint::new("local client");
63 if secure {
64 endpoint = endpoint.assume_tls();
65 }
66
67 let rocket = rocket.local_launch(endpoint).await?;
68 let cookies = RwLock::new(cookie::CookieJar::new());
69 Ok(Client { rocket, cookies, tracked })
70 }
71
72 #[doc(hidden)]
75 pub fn _test<T, F>(f: F) -> T
76 where F: FnOnce(&Self, LocalRequest<'_>, LocalResponse<'_>) -> T + Send
77 {
78 crate::async_test(async {
79 let client = Client::debug(crate::build()).await.unwrap();
80 let request = client.get("/");
81 let response = request.clone().dispatch().await;
82 f(&client, request, response)
83 })
84 }
85
86 #[inline(always)]
87 pub(crate) fn _rocket(&self) -> &Rocket<Orbit> {
88 &self.rocket
89 }
90
91 #[inline(always)]
92 pub(crate) fn _with_raw_cookies<F, T>(&self, f: F) -> T
93 where F: FnOnce(&cookie::CookieJar) -> T
94 {
95 f(&self.cookies.read())
96 }
97
98 #[inline(always)]
99 pub(crate) fn _with_raw_cookies_mut<F, T>(&self, f: F) -> T
100 where F: FnOnce(&mut cookie::CookieJar) -> T
101 {
102 f(&mut self.cookies.write())
103 }
104
105 #[inline(always)]
106 fn _req<'c, 'u: 'c, U>(&'c self, method: Method, uri: U) -> LocalRequest<'c>
107 where U: TryInto<Origin<'u>> + fmt::Display
108 {
109 LocalRequest::new(self, method, uri)
110 }
111
112 pub(crate) async fn _terminate(self) -> Rocket<Ignite> {
113 let rocket = self.rocket;
114 rocket.shutdown().notify();
115 rocket.fairings.handle_shutdown(&rocket).await;
116 rocket.deorbit()
117 }
118
119 pub_client_impl!("use rocket::local::asynchronous::Client;" @async await);
121}
122
123impl std::fmt::Debug for Client {
124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 self._rocket().fmt(f)
126 }
127}
128
129#[cfg(test)]
130mod test {
131 #[test]
132 fn test_local_client_impl_send_sync() {
133 fn assert_sync_send<T: Sync + Send>() {}
134 assert_sync_send::<super::Client>();
135 }
136}