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 reserved_space() -> usize {
113 <RootSerializer<S> as Serializer>::reserved_space()
114 }
115
116 const IS_OPTIONAL: bool = true;
117
118 const IS_POLYMORPHIC: bool = <RootSerializer<S> as Serializer>::IS_POLYMORPHIC;
119
120 const IS_SHARED_REF: bool = <RootSerializer<S> as Serializer>::IS_SHARED_REF;
121
122 const IS_WRAPPER: bool = true;
123
124 const REQUIRES_SCOPED_ACCESS: bool = S::REQUIRES_SCOPED_ACCESS;
125
126 #[inline(always)]
127 fn is_none(value: &Self::Target) -> bool {
128 value.is_none()
129 }
130
131 #[inline(always)]
132 fn dynamic_type_id(value: &Self::Target) -> Result<Option<std::any::TypeId>, Error> {
133 match value {
134 Some(value) => S::dynamic_type_id(value),
135 None => Ok(None),
136 }
137 }
138}
139
140impl<T> Serializer for Option<T>
141where
142 T: Serializer<Target = T>,
143{
144 type Target = Self;
145
146 #[inline(always)]
147 fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
148 OptionSerializer::<T>::write_data(value, context)
149 }
150
151 #[inline(always)]
152 fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
153 OptionSerializer::<T>::read_data(context)
154 }
155
156 #[inline(always)]
157 fn default_value(context: &mut ReadContext) -> Result<Self, Error> {
158 OptionSerializer::<T>::default_value(context)
159 }
160
161 #[inline(always)]
162 fn write(
163 value: &Self,
164 context: &mut WriteContext,
165 ref_mode: RefMode,
166 write_type_info: bool,
167 ) -> Result<(), Error> {
168 OptionSerializer::<T>::write(value, context, ref_mode, write_type_info)
169 }
170
171 #[inline(always)]
172 fn write_type_info_value(
173 context: &mut WriteContext,
174 target_type_id: std::any::TypeId,
175 ) -> Result<Rc<TypeInfo>, Error> {
176 OptionSerializer::<T>::write_type_info_value(context, target_type_id)
177 }
178
179 #[inline(always)]
180 fn write_with_type_info(
181 value: &Self,
182 context: &mut WriteContext,
183 ref_mode: RefMode,
184 type_info: &Rc<TypeInfo>,
185 ) -> Result<(), Error> {
186 OptionSerializer::<T>::write_with_type_info(value, context, ref_mode, type_info)
187 }
188
189 #[inline(always)]
190 fn read(
191 context: &mut ReadContext,
192 ref_mode: RefMode,
193 read_type_info: bool,
194 ) -> Result<Self, Error> {
195 OptionSerializer::<T>::read(context, ref_mode, read_type_info)
196 }
197
198 #[inline(always)]
199 fn read_with_type_info(
200 context: &mut ReadContext,
201 ref_mode: RefMode,
202 type_info: &Rc<TypeInfo>,
203 ) -> Result<Self, Error> {
204 OptionSerializer::<T>::read_with_type_info(context, ref_mode, type_info)
205 }
206
207 #[inline(always)]
208 fn write_type_info(context: &mut WriteContext) -> Result<(), Error> {
209 OptionSerializer::<T>::write_type_info(context)
210 }
211
212 #[inline(always)]
213 fn read_type_info(context: &mut ReadContext) -> Result<(), Error> {
214 OptionSerializer::<T>::read_type_info(context)
215 }
216
217 #[inline(always)]
218 fn static_type_id() -> TypeId {
219 OptionSerializer::<T>::static_type_id()
220 }
221
222 #[inline(always)]
223 fn reserved_space() -> usize {
224 OptionSerializer::<T>::reserved_space()
225 }
226
227 const IS_OPTIONAL: bool = true;
228
229 const IS_POLYMORPHIC: bool = OptionSerializer::<T>::IS_POLYMORPHIC;
230
231 const IS_SHARED_REF: bool = OptionSerializer::<T>::IS_SHARED_REF;
232
233 const IS_WRAPPER: bool = true;
234
235 const REQUIRES_SCOPED_ACCESS: bool = OptionSerializer::<T>::REQUIRES_SCOPED_ACCESS;
236
237 #[inline(always)]
238 fn is_none(value: &Self) -> bool {
239 value.is_none()
240 }
241
242 #[inline(always)]
243 fn dynamic_type_id(value: &Self) -> Result<Option<std::any::TypeId>, Error> {
244 OptionSerializer::<T>::dynamic_type_id(value)
245 }
246}