cu_sensor_payloads/
handle_payload.rs1use 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}