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