1use crate::server::{Data, Session};
2
3use std::any::{Any, TypeId};
4use std::cell::RefCell;
5use std::mem::ManuallyDrop;
6
7pub use lafere::util::PinnedFuture;
8
9fn is_req<T: Any, R: Any>() -> bool {
10 TypeId::of::<T>() == TypeId::of::<R>()
11}
12
13fn is_session<T: Any>() -> bool {
14 TypeId::of::<T>() == TypeId::of::<Session>()
15}
16
17fn is_data<T: Any>() -> bool {
18 TypeId::of::<T>() == TypeId::of::<Data>()
19}
20
21#[doc(hidden)]
23#[inline]
24pub fn valid_data_as_ref<T: Any, R: Any>(data: &Data) -> bool {
25 is_req::<T, R>()
26 || is_session::<T>()
27 || is_data::<T>()
28 || data.exists::<T>()
29}
30
31#[doc(hidden)]
33#[inline]
34pub fn valid_data_as_owned<T: Any, R: Any>(_data: &Data) -> bool {
35 is_req::<T, R>()
36}
37
38#[doc(hidden)]
39pub struct DataManager<T> {
40 inner: RefCell<Option<T>>,
41}
42
43impl<T> DataManager<T> {
44 pub fn new(val: T) -> Self {
45 Self {
46 inner: RefCell::new(Some(val)),
47 }
48 }
49
50 #[inline]
53 pub fn take(&self) -> T {
54 self.inner.borrow_mut().take().unwrap()
55 }
56
57 #[inline]
60 pub fn as_ref(&self) -> &T {
61 let r = self.inner.borrow();
62 let r = ManuallyDrop::new(r);
63 unsafe { &*(&**r as *const Option<T>) }.as_ref().unwrap()
66 }
67
68 #[inline]
71 pub fn take_owned(mut self) -> T {
72 self.inner.get_mut().take().unwrap()
73 }
74}
75
76#[doc(hidden)]
77#[inline]
78pub fn get_data_as_ref<'a, T: Any, R: Any>(
79 data: &'a Data,
80 session: &'a Session,
81 req: &'a DataManager<R>,
82) -> &'a T {
83 if is_req::<T, R>() {
84 let req = req.as_ref();
85 <dyn Any>::downcast_ref(req).unwrap()
86 } else if is_session::<T>() {
87 <dyn Any>::downcast_ref(session).unwrap()
88 } else if is_data::<T>() {
89 <dyn Any>::downcast_ref(data).unwrap()
90 } else {
91 data.get::<T>().unwrap()
92 }
93}
94
95#[doc(hidden)]
96#[inline]
97pub fn get_data_as_owned<T: Any, R: Any>(
98 _data: &Data,
99 _session: &Session,
100 req: &DataManager<R>,
101) -> T {
102 if is_req::<T, R>() {
103 let req = req.take();
104 unsafe { transform_owned::<T, R>(req) }
105 } else {
106 unreachable!()
107 }
108}
109
110#[doc(hidden)]
112#[inline]
113pub(crate) unsafe fn transform_owned<T: Any + Sized, R: Any>(from: R) -> T {
114 let mut from = ManuallyDrop::new(from);
115 (&mut from as *mut ManuallyDrop<R> as *mut T).read()
116}