Skip to main content

cu_sensor_payloads/
handle_payload.rs

1use alloc::boxed::Box;
2use bincode::de::Decoder;
3use bincode::enc::Encoder;
4use bincode::error::{DecodeError, EncodeError};
5use bincode::{Decode, Encode};
6use core::fmt::Debug;
7use core::marker::PhantomData;
8use cu29::prelude::*;
9use serde::{Deserialize, Deserializer, Serialize, Serializer};
10
11pub trait CuHandlePayloadMeta {
12    const TYPE_PATH: &'static str;
13    const SHORT_TYPE_PATH: &'static str;
14    const TYPE_IDENT: Option<&'static str>;
15    const CRATE_NAME: Option<&'static str>;
16    const MODULE_PATH: Option<&'static str>;
17}
18
19pub trait CuHandlePayloadInit: Debug + Send + Sync + 'static {
20    fn boxed_init() -> Box<Self>;
21
22    fn decode_boxed<D>(decoder: &mut D) -> Result<Box<Self>, DecodeError>
23    where
24        Self: Decode<()>,
25        D: Decoder<Context = ()>,
26    {
27        let inner = Self::decode(decoder)?;
28        Ok(Box::new(inner))
29    }
30}
31
32#[derive(Reflect)]
33#[reflect(from_reflect = false, no_field_bounds, type_path = false)]
34pub struct CuHandlePayload<T, M>
35where
36    T: Debug + Send + Sync + 'static,
37    M: CuHandlePayloadMeta + 'static,
38{
39    #[reflect(ignore)]
40    pub handle: CuHandle<T>,
41    #[reflect(ignore)]
42    _meta: PhantomData<M>,
43}
44
45impl<T, M> Debug for CuHandlePayload<T, M>
46where
47    T: Debug + Send + Sync + 'static,
48    M: CuHandlePayloadMeta + 'static,
49{
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        f.debug_struct("CuHandlePayload")
52            .field("handle", &self.handle)
53            .finish()
54    }
55}
56
57impl<T, M> Clone for CuHandlePayload<T, M>
58where
59    T: Debug + Send + Sync + 'static,
60    M: CuHandlePayloadMeta + 'static,
61{
62    fn clone(&self) -> Self {
63        Self {
64            handle: self.handle.clone(),
65            _meta: PhantomData,
66        }
67    }
68}
69
70impl<T, M> Default for CuHandlePayload<T, M>
71where
72    T: CuHandlePayloadInit,
73    M: CuHandlePayloadMeta + 'static,
74{
75    fn default() -> Self {
76        Self::from_box(T::boxed_init())
77    }
78}
79
80impl<T, M> TypePath for CuHandlePayload<T, M>
81where
82    T: Debug + Send + Sync + 'static,
83    M: CuHandlePayloadMeta + 'static,
84{
85    fn type_path() -> &'static str {
86        M::TYPE_PATH
87    }
88
89    fn short_type_path() -> &'static str {
90        M::SHORT_TYPE_PATH
91    }
92
93    fn type_ident() -> Option<&'static str> {
94        M::TYPE_IDENT
95    }
96
97    fn crate_name() -> Option<&'static str> {
98        M::CRATE_NAME
99    }
100
101    fn module_path() -> Option<&'static str> {
102        M::MODULE_PATH
103    }
104}
105
106impl<T, M> CuHandlePayload<T, M>
107where
108    T: Debug + Send + Sync + 'static,
109    M: CuHandlePayloadMeta + 'static,
110{
111    pub fn from_handle(handle: CuHandle<T>) -> Self {
112        Self {
113            handle,
114            _meta: PhantomData,
115        }
116    }
117
118    pub fn new_detached(inner: T) -> Self {
119        Self::from_handle(CuHandle::new_detached(inner))
120    }
121
122    pub fn from_box(inner: Box<T>) -> Self {
123        Self::from_handle(CuHandle::new_detached_box(inner))
124    }
125
126    pub fn with_inner<R>(&self, f: impl FnOnce(&T) -> R) -> R {
127        self.handle.with_inner(|inner| f(inner.as_ref()))
128    }
129
130    pub fn with_inner_mut<R>(&mut self, f: impl FnOnce(&mut T) -> R) -> R {
131        self.handle.with_inner_mut(|inner| f(inner.as_mut()))
132    }
133}
134
135impl<T, M> Serialize for CuHandlePayload<T, M>
136where
137    T: Debug + Send + Sync + Serialize + 'static,
138    M: CuHandlePayloadMeta + 'static,
139{
140    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
141        self.with_inner(|inner| inner.serialize(serializer))
142    }
143}
144
145impl<'de, T, M> Deserialize<'de> for CuHandlePayload<T, M>
146where
147    T: Debug + Send + Sync + Deserialize<'de> + 'static,
148    M: CuHandlePayloadMeta + 'static,
149{
150    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
151        let inner = Box::<T>::deserialize(deserializer)?;
152        Ok(Self::from_box(inner))
153    }
154}
155
156impl<T, M> Encode for CuHandlePayload<T, M>
157where
158    T: Debug + Send + Sync + Encode + 'static,
159    M: CuHandlePayloadMeta + 'static,
160{
161    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
162        self.with_inner(|inner| inner.encode(encoder))
163    }
164}
165
166impl<T, M> Decode<()> for CuHandlePayload<T, M>
167where
168    T: CuHandlePayloadInit + Decode<()>,
169    M: CuHandlePayloadMeta + 'static,
170{
171    fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
172        let inner = T::decode_boxed(decoder)?;
173        Ok(Self::from_box(inner))
174    }
175}