1use crate::context::{ReadContext, WriteContext};
19use crate::error::Error;
20use crate::resolver::{RefMode, TypeInfo};
21use crate::serializer::codec::OptionCodec;
22use crate::serializer::Serializer;
23use crate::type_id::TypeId;
24use std::marker::PhantomData;
25use std::rc::Rc;
26
27pub struct OptionSerializer<S>(PhantomData<fn() -> S>);
29
30type RootSerializer<S> = OptionCodec<<S as Serializer>::Target, S, false>;
31
32impl<S: Serializer> Serializer for OptionSerializer<S> {
33 type Target = Option<S::Target>;
34
35 #[inline(always)]
36 fn write_data(value: &Self::Target, context: &mut WriteContext) -> Result<(), Error> {
37 <RootSerializer<S> as Serializer>::write_data(value, context)
38 }
39
40 #[inline(always)]
41 fn read_data(context: &mut ReadContext) -> Result<Self::Target, Error> {
42 <RootSerializer<S> as Serializer>::read_data(context)
43 }
44
45 #[inline(always)]
46 fn default_value(context: &mut ReadContext) -> Result<Self::Target, Error> {
47 <RootSerializer<S> as Serializer>::default_value(context)
48 }
49
50 #[inline(always)]
51 fn write(
52 value: &Self::Target,
53 context: &mut WriteContext,
54 ref_mode: RefMode,
55 write_type_info: bool,
56 ) -> Result<(), Error> {
57 <RootSerializer<S> as Serializer>::write(value, context, ref_mode, write_type_info)
58 }
59
60 #[inline(always)]
61 fn write_type_info_value(
62 context: &mut WriteContext,
63 target_type_id: std::any::TypeId,
64 ) -> Result<Rc<TypeInfo>, Error> {
65 <RootSerializer<S> as Serializer>::write_type_info_value(context, target_type_id)
66 }
67
68 #[inline(always)]
69 fn write_with_type_info(
70 value: &Self::Target,
71 context: &mut WriteContext,
72 ref_mode: RefMode,
73 type_info: &Rc<TypeInfo>,
74 ) -> Result<(), Error> {
75 <RootSerializer<S> as Serializer>::write_with_type_info(value, context, ref_mode, type_info)
76 }
77
78 #[inline(always)]
79 fn read(
80 context: &mut ReadContext,
81 ref_mode: RefMode,
82 read_type_info: bool,
83 ) -> Result<Self::Target, Error> {
84 <RootSerializer<S> as Serializer>::read(context, ref_mode, read_type_info)
85 }
86
87 #[inline(always)]
88 fn read_with_type_info(
89 context: &mut ReadContext,
90 ref_mode: RefMode,
91 type_info: &Rc<TypeInfo>,
92 ) -> Result<Self::Target, Error> {
93 <RootSerializer<S> as Serializer>::read_with_type_info(context, ref_mode, type_info)
94 }
95
96 #[inline(always)]
97 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
98 <RootSerializer<S> as Serializer>::write_type_info(context)
99 }
100
101 #[inline(always)]
102 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
103 <RootSerializer<S> as Serializer>::read_type_info(context)
104 }
105
106 #[inline(always)]
107 fn static_type_id() -> TypeId {
108 <RootSerializer<S> as Serializer>::static_type_id()
109 }
110
111 #[inline(always)]
112 fn metadata_target_type_id() -> std::any::TypeId {
113 S::metadata_target_type_id()
114 }
115
116 #[inline(always)]
117 fn reserved_space() -> usize {
118 <RootSerializer<S> as Serializer>::reserved_space()
119 }
120
121 const IS_OPTIONAL: bool = true;
122
123 const IS_POLYMORPHIC: bool = <RootSerializer<S> as Serializer>::IS_POLYMORPHIC;
124
125 const IS_SHARED_REF: bool = <RootSerializer<S> as Serializer>::IS_SHARED_REF;
126
127 const IS_WRAPPER: bool = true;
128
129 const REQUIRES_SCOPED_ACCESS: bool = S::REQUIRES_SCOPED_ACCESS;
130
131 const READ_DATA_ALWAYS_ADVANCES: bool = S::READ_DATA_ALWAYS_ADVANCES;
132
133 #[inline(always)]
134 fn is_none(value: &Self::Target) -> bool {
135 value.is_none()
136 }
137
138 #[inline(always)]
139 fn dynamic_type_id(value: &Self::Target) -> Result<Option<std::any::TypeId>, Error> {
140 match value {
141 Some(value) => S::dynamic_type_id(value),
142 None => Ok(None),
143 }
144 }
145}
146
147impl<T> Serializer for Option<T>
148where
149 T: Serializer<Target = T>,
150{
151 type Target = Self;
152
153 #[inline(always)]
154 fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
155 OptionSerializer::<T>::write_data(value, context)
156 }
157
158 #[inline(always)]
159 fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
160 OptionSerializer::<T>::read_data(context)
161 }
162
163 #[inline(always)]
164 fn default_value(context: &mut ReadContext) -> Result<Self, Error> {
165 OptionSerializer::<T>::default_value(context)
166 }
167
168 #[inline(always)]
169 fn write(
170 value: &Self,
171 context: &mut WriteContext,
172 ref_mode: RefMode,
173 write_type_info: bool,
174 ) -> Result<(), Error> {
175 OptionSerializer::<T>::write(value, context, ref_mode, write_type_info)
176 }
177
178 #[inline(always)]
179 fn write_type_info_value(
180 context: &mut WriteContext,
181 target_type_id: std::any::TypeId,
182 ) -> Result<Rc<TypeInfo>, Error> {
183 OptionSerializer::<T>::write_type_info_value(context, target_type_id)
184 }
185
186 #[inline(always)]
187 fn write_with_type_info(
188 value: &Self,
189 context: &mut WriteContext,
190 ref_mode: RefMode,
191 type_info: &Rc<TypeInfo>,
192 ) -> Result<(), Error> {
193 OptionSerializer::<T>::write_with_type_info(value, context, ref_mode, type_info)
194 }
195
196 #[inline(always)]
197 fn read(
198 context: &mut ReadContext,
199 ref_mode: RefMode,
200 read_type_info: bool,
201 ) -> Result<Self, Error> {
202 OptionSerializer::<T>::read(context, ref_mode, read_type_info)
203 }
204
205 #[inline(always)]
206 fn read_with_type_info(
207 context: &mut ReadContext,
208 ref_mode: RefMode,
209 type_info: &Rc<TypeInfo>,
210 ) -> Result<Self, Error> {
211 OptionSerializer::<T>::read_with_type_info(context, ref_mode, type_info)
212 }
213
214 #[inline(always)]
215 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
216 OptionSerializer::<T>::write_type_info(context)
217 }
218
219 #[inline(always)]
220 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
221 OptionSerializer::<T>::read_type_info(context)
222 }
223
224 #[inline(always)]
225 fn static_type_id() -> TypeId {
226 OptionSerializer::<T>::static_type_id()
227 }
228
229 #[inline(always)]
230 fn metadata_target_type_id() -> std::any::TypeId {
231 T::metadata_target_type_id()
232 }
233
234 #[inline(always)]
235 fn reserved_space() -> usize {
236 OptionSerializer::<T>::reserved_space()
237 }
238
239 const IS_OPTIONAL: bool = true;
240
241 const IS_POLYMORPHIC: bool = OptionSerializer::<T>::IS_POLYMORPHIC;
242
243 const IS_SHARED_REF: bool = OptionSerializer::<T>::IS_SHARED_REF;
244
245 const IS_WRAPPER: bool = true;
246
247 const REQUIRES_SCOPED_ACCESS: bool = OptionSerializer::<T>::REQUIRES_SCOPED_ACCESS;
248
249 const READ_DATA_ALWAYS_ADVANCES: bool = T::READ_DATA_ALWAYS_ADVANCES;
250
251 #[inline(always)]
252 fn is_none(value: &Self) -> bool {
253 value.is_none()
254 }
255
256 #[inline(always)]
257 fn dynamic_type_id(value: &Self) -> Result<Option<std::any::TypeId>, Error> {
258 OptionSerializer::<T>::dynamic_type_id(value)
259 }
260}