1use std::{borrow::Cow, marker::PhantomData, ops::*, time::SystemTime};
4
5use futures_channel::oneshot;
6
7use crate::core::cookie::*;
8
9pub struct Cookie(CookieImpl);
10
11pub struct CookieJar(CookieJarImpl);
12
13pub struct CookieIterator<'a> {
14 inner: CookieIteratorImpl,
15 _phantom: PhantomData<&'a u8>,
16}
17
18impl Cookie {
19 pub fn new(name: &str, value: &str) -> Self { Self(CookieImpl::new(name, value)) }
20
21 pub fn creation_time(&self) -> SystemTime { self.0.creation_time() }
22
23 pub fn expires(&self) -> Option<SystemTime> { self.0.expires() }
24
25 pub fn domain(&self) -> Cow<'_, str> { self.0.domain() }
26
27 pub fn is_http_only(&self) -> bool { self.0.is_http_only() }
28
29 pub fn name(&self) -> Cow<'_, str> { self.0.name() }
30
31 pub fn path(&self) -> Cow<'_, str> { self.0.path() }
32
33 pub fn is_secure(&self) -> bool { self.0.is_secure() }
34
35 pub fn value(&self) -> Cow<'_, str> { self.0.value() }
36
37 pub fn make_http_only(&mut self) -> &mut Self {
38 self.0.make_http_only();
39 self
40 }
41
42 pub fn make_secure(&mut self) -> &mut Self {
43 self.0.make_secure();
44 self
45 }
46
47 pub fn set_creation_time(&mut self, time: &SystemTime) -> &mut Self {
48 self.0.set_creation_time(time);
49 self
50 }
51
52 pub fn set_expires(&mut self, time: &SystemTime) -> &mut Self {
53 self.0.set_expires(time);
54 self
55 }
56
57 pub fn set_domain(&mut self, domain: &str) -> &mut Self {
58 self.0.set_domain(domain);
59 self
60 }
61
62 pub fn set_name(&mut self, name: &str) -> &mut Self {
63 self.0.set_name(name);
64 self
65 }
66
67 pub fn set_path(&mut self, path: &str) -> &mut Self {
68 self.0.set_path(path);
69 self
70 }
71
72 pub fn set_value(&mut self, value: &str) -> &mut Self {
73 self.0.set_value(value);
74 self
75 }
76}
77
78impl Drop for Cookie {
79 fn drop(&mut self) { self.0.free(); }
80}
81
82impl<'a> CookieIterator<'a> {
83 pub async fn next(&mut self) -> Option<Cookie> {
84 let (tx, rx) = oneshot::channel::<Option<Cookie>>();
85
86 let more = self._next(|result| {
87 if let Err(_) = tx.send(result) {
88 panic!("unable to send cookie iterator next result back");
89 }
90 });
91
92 if !more {
93 return None;
94 }
95
96 rx.await.unwrap()
97 }
98
99 fn _next<H>(&mut self, on_next: H) -> bool
100 where
101 H: FnOnce(Option<Cookie>),
102 {
103 let data = Box::into_raw(Box::new(on_next));
104
105 let called_closure = self
106 .inner
107 .next(cookie_iterator_next_handler::<H>, data as _);
108
109 if !called_closure {
110 unsafe {
111 let _ = Box::from_raw(data);
112 }
113 }
114
115 called_closure
116 }
117}
118
119impl<'a> Drop for CookieIterator<'a> {
120 fn drop(&mut self) { self.inner.free(); }
121}
122
123impl CookieJar {
124 pub async fn clear(&mut self, url: &str) -> usize { self.delete(url, "").await }
128
129 pub async fn clear_all(&mut self) -> usize { self.clear("").await }
131
132 fn _delete<H>(&mut self, url: &str, name: &str, on_complete: H)
133 where
134 H: FnOnce(usize),
135 {
136 let data = Box::into_raw(Box::new(on_complete));
137
138 self.0
139 .delete(url, name, cookie_delete_callback::<H>, data as _);
140 }
141
142 pub async fn delete(&mut self, url: &str, name: &str) -> usize {
148 let (tx, rx) = oneshot::channel::<usize>();
149
150 self._delete(url, name, |result| {
151 tx.send(result)
152 .expect("unable to send back cookie delete count");
153 });
154
155 rx.await.unwrap()
156 }
157
158 pub async fn delete_all(&mut self, name: &str) -> usize { self.delete("", name).await }
160
161 pub async fn find(&self, url: &str, name: &str, include_http_only: bool) -> Option<Cookie> {
165 let mut iter = self.iter(url, include_http_only);
166
167 while let Some(cookie) = iter.next().await {
168 if cookie.name() == name {
169 return Some(cookie);
170 }
171 }
172
173 None
174 }
175
176 pub async fn find_from_all(&self, name: &str) -> Option<Cookie> {
178 let mut iter = self.iter_all();
179
180 while let Some(cookie) = iter.next().await {
181 if cookie.name() == name {
182 return Some(cookie);
183 }
184 }
185
186 None
187 }
188
189 pub(crate) fn global() -> Option<Self> { CookieJarImpl::global().map(|i| Self(i)) }
190
191 pub fn iter<'a>(&'a self, url: &str, include_http_only: bool) -> CookieIterator<'a> {
205 let inner = self.0.iterator(url, include_http_only);
206
207 CookieIterator {
208 inner,
209 _phantom: PhantomData,
210 }
211 }
212
213 pub fn iter_all<'a>(&'a self) -> CookieIterator<'a> {
216 let inner = self.0.iterator_all();
217
218 CookieIterator {
219 inner,
220 _phantom: PhantomData,
221 }
222 }
223
224 fn _store<'a, H>(&mut self, url: &str, cookie: &Cookie, on_complete: H)
225 where
226 H: FnOnce(Result<(), CookieStorageError>) + 'a,
227 {
228 let data = Box::into_raw(Box::new(on_complete));
229
230 self.0.store(
231 url.into(),
232 &cookie.0,
233 Some(cookie_store_callback::<'a, H>),
234 data as _,
235 );
236 }
237
238 pub async fn store(&mut self, url: &str, cookie: &Cookie) -> Result<(), CookieStorageError> {
240 let (tx, rx) = oneshot::channel::<Result<(), CookieStorageError>>();
241
242 self._store(url, cookie, |result| {
243 tx.send(result)
244 .expect("unable to retrieve cookie storage error");
245 });
246
247 rx.await.unwrap()
248 }
249}
250
251impl Drop for CookieJar {
252 fn drop(&mut self) { self.0.free(); }
253}
254
255unsafe fn cookie_delete_callback<'a, H>(_handle: CookieJarImpl, cb_data: *mut (), deleted: usize)
256where
257 H: FnOnce(usize) + 'a,
258{
259 let data_ptr = cb_data as *mut H;
260 let data: Box<H> = Box::from_raw(data_ptr);
261
262 (*data)(deleted);
263}
264
265unsafe fn cookie_store_callback<'a, H>(
266 _handle: CookieJarImpl, cb_data: *mut (), result: Result<(), CookieStorageError>,
267) where
268 H: FnOnce(Result<(), CookieStorageError>) + 'a,
269{
270 let data_ptr = cb_data as *mut H;
271 let data: Box<H> = Box::from_raw(data_ptr);
272
273 (*data)(result);
274}
275
276unsafe fn cookie_iterator_next_handler<H>(
277 _handle: CookieIteratorImpl, cb_data: *mut (), cookie: Option<CookieImpl>,
278) where
279 H: FnOnce(Option<Cookie>),
280{
281 let data_ptr = cb_data as *mut H;
282 let data: Box<H> = Box::from_raw(data_ptr);
283
284 (*data)(cookie.map(|c| Cookie(c)));
285}