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