1use crate::context::{ReadContext, WriteContext};
19use crate::ensure;
20use crate::error::Error;
21use crate::resolver::{RefFlag, RefMode};
22use crate::resolver::{TypeInfo, TypeResolver};
23use crate::serializer::util::write_dyn_data_generic;
24use crate::serializer::{ForyDefault, Serializer};
25use crate::type_id::TypeId;
26use std::any::Any;
27use std::rc::Rc;
28use std::sync::Arc;
29
30#[inline(always)]
31fn resolve_registered_type_id(
32 type_resolver: &TypeResolver,
33 concrete_type_id: std::any::TypeId,
34) -> Result<TypeId, Error> {
35 type_resolver
36 .get_fory_type_id(concrete_type_id)
37 .ok_or_else(|| Error::type_error("Type not registered"))
38}
39
40#[inline]
44fn check_generic_container_type(type_info: &TypeInfo) -> Result<(), Error> {
45 let type_id = type_info.get_type_id();
46 if type_id == TypeId::LIST || type_id == TypeId::SET || type_id == TypeId::MAP {
47 return Err(Error::type_error(
48 "Cannot deserialize generic container types (Vec, HashSet, HashMap) polymorphically \
49 via Box/Rc/Arc/Weak<dyn Any>. The serialization protocol does not preserve the element type \
50 information needed to distinguish between different generic instantiations \
51 (e.g., Vec<StructA> vs Vec<StructB>). Consider wrapping the container in a \
52 named struct type instead.",
53 ));
54 }
55 Ok(())
56}
57
58pub fn deserialize_any_box(context: &mut ReadContext) -> Result<Box<dyn Any>, Error> {
60 context.inc_depth()?;
61 let ref_flag = context.reader.read_i8()?;
62 if ref_flag != RefFlag::NotNullValue as i8 {
63 return Err(Error::invalid_ref("Expected NotNullValue for Box<dyn Any>"));
64 }
65 let typeinfo = context.read_any_type_info()?;
66 check_generic_container_type(&typeinfo)?;
68 let result = typeinfo
69 .get_harness()
70 .read_polymorphic_data(context, &typeinfo);
71 context.dec_depth();
72 result
73}
74
75impl ForyDefault for Box<dyn Any> {
76 fn fory_default() -> Self {
77 Box::new(())
78 }
79}
80
81impl Serializer for Box<dyn Any> {
82 fn fory_write(
83 &self,
84 context: &mut WriteContext,
85 ref_mode: RefMode,
86 write_type_info: bool,
87 has_generics: bool,
88 ) -> Result<(), Error> {
89 write_box_any(
90 self.as_ref(),
91 context,
92 ref_mode,
93 write_type_info,
94 has_generics,
95 )
96 }
97
98 fn fory_write_data_generic(
99 &self,
100 context: &mut WriteContext,
101 has_generics: bool,
102 ) -> Result<(), Error> {
103 let concrete_type_id = (**self).type_id();
104 let typeinfo = context.get_type_info(&concrete_type_id)?;
105 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
106 serializer_fn(&**self, context, has_generics)
107 }
108
109 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
110 self.fory_write_data_generic(context, false)
111 }
112
113 fn fory_read(
114 context: &mut ReadContext,
115 ref_mode: RefMode,
116 read_type_info: bool,
117 ) -> Result<Self, Error> {
118 read_box_any(context, ref_mode, read_type_info, None)
119 }
120
121 fn fory_read_with_type_info(
122 context: &mut ReadContext,
123 ref_mode: RefMode,
124 type_info: Rc<TypeInfo>,
125 ) -> Result<Self, Error>
126 where
127 Self: Sized + ForyDefault,
128 {
129 read_box_any(context, ref_mode, false, Some(type_info))
130 }
131
132 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
133 Err(Error::not_allowed(
134 "fory_read_data should not be called directly on polymorphic Rc<dyn Any> trait object",
135 ))
136 }
137
138 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
139 Err(Error::type_error(
140 "Box<dyn Any> has no static type ID - use fory_type_id_dyn",
141 ))
142 }
143
144 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
145 resolve_registered_type_id(type_resolver, (**self).type_id())
146 }
147
148 fn fory_concrete_type_id(&self) -> std::any::TypeId {
149 (**self).type_id()
150 }
151
152 fn fory_is_polymorphic() -> bool {
153 true
154 }
155
156 fn fory_is_shared_ref() -> bool {
157 false
158 }
159
160 fn fory_static_type_id() -> TypeId {
161 TypeId::UNKNOWN
162 }
163
164 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
165 Ok(())
167 }
168
169 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
170 Ok(())
172 }
173
174 fn as_any(&self) -> &dyn Any {
175 &**self
176 }
177}
178
179pub fn write_box_any(
180 value: &dyn Any,
181 context: &mut WriteContext,
182 ref_mode: RefMode,
183 write_type_info: bool,
184 has_generics: bool,
185) -> Result<(), Error> {
186 if ref_mode != RefMode::None {
187 context.writer.write_i8(RefFlag::NotNullValue as i8);
188 }
189 let concrete_type_id = value.type_id();
190 let typeinfo = if write_type_info {
191 context.write_any_type_info(TypeId::UNKNOWN as u32, concrete_type_id)?
192 } else {
193 context.get_type_info(&concrete_type_id)?
194 };
195 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
196 serializer_fn(value, context, has_generics)
197}
198
199pub fn read_box_any(
200 context: &mut ReadContext,
201 ref_mode: RefMode,
202 read_type_info: bool,
203 type_info: Option<Rc<TypeInfo>>,
204) -> Result<Box<dyn Any>, Error> {
205 context.inc_depth()?;
206 let ref_flag = if ref_mode != RefMode::None {
207 context.reader.read_i8()?
208 } else {
209 RefFlag::NotNullValue as i8
210 };
211 if ref_flag != RefFlag::NotNullValue as i8 {
212 return Err(Error::invalid_data(
213 "Expected NotNullValue for Box<dyn Any>",
214 ));
215 }
216 let typeinfo = if let Some(type_info) = type_info {
217 type_info
218 } else {
219 ensure!(
220 read_type_info,
221 Error::invalid_data("Type info must be read for Box<dyn Any>")
222 );
223 context.read_any_type_info()?
224 };
225 check_generic_container_type(&typeinfo)?;
227 let result = typeinfo
228 .get_harness()
229 .read_polymorphic_data(context, &typeinfo);
230 context.dec_depth();
231 result
232}
233
234impl ForyDefault for Rc<dyn Any> {
235 fn fory_default() -> Self {
236 Rc::new(())
237 }
238}
239
240impl Serializer for Rc<dyn Any> {
241 fn fory_write(
242 &self,
243 context: &mut WriteContext,
244 ref_mode: RefMode,
245 write_type_info: bool,
246 has_generics: bool,
247 ) -> Result<(), Error> {
248 if ref_mode == RefMode::None
249 || !context
250 .ref_writer
251 .try_write_rc_ref(&mut context.writer, self)
252 {
253 let concrete_type_id: std::any::TypeId = (**self).type_id();
254 let write_data_fn = if write_type_info {
255 let typeinfo =
256 context.write_any_type_info(TypeId::UNKNOWN as u32, concrete_type_id)?;
257 typeinfo.get_harness().get_write_data_fn()
258 } else {
259 context
260 .get_type_info(&concrete_type_id)?
261 .get_harness()
262 .get_write_data_fn()
263 };
264 write_data_fn(&**self, context, has_generics)?;
265 }
266 Ok(())
267 }
268
269 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
270 write_dyn_data_generic(self, context, false)
271 }
272
273 fn fory_write_data_generic(
274 &self,
275 context: &mut WriteContext,
276 has_generics: bool,
277 ) -> Result<(), Error> {
278 write_dyn_data_generic(self, context, has_generics)
279 }
280
281 fn fory_read(
282 context: &mut ReadContext,
283 ref_mode: RefMode,
284 read_type_info: bool,
285 ) -> Result<Self, Error> {
286 read_rc_any(context, ref_mode, read_type_info, None)
287 }
288
289 fn fory_read_with_type_info(
290 context: &mut ReadContext,
291 ref_mode: RefMode,
292 type_info: Rc<TypeInfo>,
293 ) -> Result<Self, Error>
294 where
295 Self: Sized + ForyDefault,
296 {
297 read_rc_any(context, ref_mode, false, Some(type_info))
298 }
299
300 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
301 Err(Error::not_allowed(format!(
302 "fory_read_data should not be called directly on polymorphic Rc<dyn {}> trait object",
303 stringify!($trait_name)
304 )))
305 }
306
307 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
308 Err(Error::type_error(
309 "Rc<dyn Any> has no static type ID - use fory_type_id_dyn",
310 ))
311 }
312
313 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
314 resolve_registered_type_id(type_resolver, (**self).type_id())
315 }
316
317 fn fory_concrete_type_id(&self) -> std::any::TypeId {
318 (**self).type_id()
319 }
320
321 fn fory_is_shared_ref() -> bool {
322 true
323 }
324
325 fn fory_is_polymorphic() -> bool {
326 true
327 }
328
329 fn fory_static_type_id() -> TypeId {
330 TypeId::UNKNOWN
331 }
332
333 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
334 Ok(())
336 }
337
338 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
339 Ok(())
341 }
342
343 fn as_any(&self) -> &dyn Any {
344 &**self
345 }
346}
347
348pub fn read_rc_any(
349 context: &mut ReadContext,
350 ref_mode: RefMode,
351 read_type_info: bool,
352 type_info: Option<Rc<TypeInfo>>,
353) -> Result<Rc<dyn Any>, Error> {
354 let ref_flag = if ref_mode != RefMode::None {
355 context.ref_reader.read_ref_flag(&mut context.reader)?
356 } else {
357 RefFlag::NotNullValue
358 };
359 match ref_flag {
360 RefFlag::Null => Err(Error::invalid_ref("Rc<dyn Any> cannot be null")),
361 RefFlag::Ref => {
362 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
363 context
364 .ref_reader
365 .get_rc_ref::<dyn Any>(ref_id)
366 .ok_or_else(|| {
367 Error::invalid_data(format!("Rc<dyn Any> reference {} not found", ref_id))
368 })
369 }
370 RefFlag::NotNullValue => {
371 context.inc_depth()?;
372 let typeinfo = if read_type_info {
373 context.read_any_type_info()?
374 } else {
375 type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
376 };
377 check_generic_container_type(&typeinfo)?;
379 let boxed = typeinfo
380 .get_harness()
381 .read_polymorphic_data(context, &typeinfo)?;
382 context.dec_depth();
383 Ok(Rc::<dyn Any>::from(boxed))
384 }
385 RefFlag::RefValue => {
386 context.inc_depth()?;
387 let typeinfo = if read_type_info {
388 context.read_any_type_info()?
389 } else {
390 type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
391 };
392 check_generic_container_type(&typeinfo)?;
394 let boxed = typeinfo
395 .get_harness()
396 .read_polymorphic_data(context, &typeinfo)?;
397 context.dec_depth();
398 let rc: Rc<dyn Any> = Rc::from(boxed);
399 context.ref_reader.store_rc_ref(rc.clone());
400 Ok(rc)
401 }
402 }
403}
404
405impl ForyDefault for Arc<dyn Any> {
406 fn fory_default() -> Self {
407 Arc::new(())
408 }
409}
410
411impl Serializer for Arc<dyn Any> {
412 fn fory_write(
413 &self,
414 context: &mut WriteContext,
415 ref_mode: RefMode,
416 write_type_info: bool,
417 has_generics: bool,
418 ) -> Result<(), Error> {
419 if ref_mode == RefMode::None
420 || !context
421 .ref_writer
422 .try_write_arc_ref(&mut context.writer, self)
423 {
424 let concrete_type_id: std::any::TypeId = (**self).type_id();
425 if write_type_info {
426 let typeinfo =
427 context.write_any_type_info(TypeId::UNKNOWN as u32, concrete_type_id)?;
428 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
429 serializer_fn(&**self, context, has_generics)?;
430 } else {
431 let serializer_fn = context
432 .get_type_info(&concrete_type_id)?
433 .get_harness()
434 .get_write_data_fn();
435 serializer_fn(&**self, context, has_generics)?;
436 }
437 }
438 Ok(())
439 }
440
441 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
442 write_dyn_data_generic(self, context, false)
443 }
444
445 fn fory_write_data_generic(
446 &self,
447 context: &mut WriteContext,
448 has_generics: bool,
449 ) -> Result<(), Error> {
450 write_dyn_data_generic(self, context, has_generics)
451 }
452
453 fn fory_read(
454 context: &mut ReadContext,
455 ref_mode: RefMode,
456 read_type_info: bool,
457 ) -> Result<Self, Error> {
458 read_arc_any(context, ref_mode, read_type_info, None)
459 }
460
461 fn fory_read_with_type_info(
462 context: &mut ReadContext,
463 ref_mode: RefMode,
464 type_info: Rc<TypeInfo>,
465 ) -> Result<Self, Error>
466 where
467 Self: Sized + ForyDefault,
468 {
469 read_arc_any(context, ref_mode, false, Some(type_info))
470 }
471
472 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
473 Err(Error::not_allowed(format!(
474 "fory_read_data should not be called directly on polymorphic Rc<dyn {}> trait object",
475 stringify!($trait_name)
476 )))
477 }
478
479 fn fory_get_type_id(_type_resolver: &TypeResolver) -> Result<TypeId, Error> {
480 Err(Error::type_error(
481 "Arc<dyn Any> has no static type ID - use fory_type_id_dyn",
482 ))
483 }
484
485 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
486 resolve_registered_type_id(type_resolver, (**self).type_id())
487 }
488
489 fn fory_concrete_type_id(&self) -> std::any::TypeId {
490 (**self).type_id()
491 }
492
493 fn fory_is_polymorphic() -> bool {
494 true
495 }
496
497 fn fory_is_shared_ref() -> bool {
498 true
499 }
500
501 fn fory_static_type_id() -> TypeId {
502 TypeId::UNKNOWN
503 }
504
505 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
506 Ok(())
508 }
509
510 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
511 Ok(())
513 }
514
515 fn as_any(&self) -> &dyn Any {
516 &**self
517 }
518}
519
520pub fn read_arc_any(
521 context: &mut ReadContext,
522 ref_mode: RefMode,
523 read_type_info: bool,
524 type_info: Option<Rc<TypeInfo>>,
525) -> Result<Arc<dyn Any>, Error> {
526 let ref_flag = if ref_mode != RefMode::None {
527 context.ref_reader.read_ref_flag(&mut context.reader)?
528 } else {
529 RefFlag::NotNullValue
530 };
531 match ref_flag {
532 RefFlag::Null => Err(Error::invalid_ref("Arc<dyn Any> cannot be null")),
533 RefFlag::Ref => {
534 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
535 context
536 .ref_reader
537 .get_arc_ref::<dyn Any>(ref_id)
538 .ok_or_else(|| {
539 Error::invalid_data(format!("Arc<dyn Any> reference {} not found", ref_id))
540 })
541 }
542 RefFlag::NotNullValue => {
543 context.inc_depth()?;
544 let typeinfo = if read_type_info {
545 context.read_any_type_info()?
546 } else {
547 type_info
548 .ok_or_else(|| Error::type_error("No type info found for read Arc<dyn Any>"))?
549 };
550 check_generic_container_type(&typeinfo)?;
552 let boxed = typeinfo
553 .get_harness()
554 .read_polymorphic_data(context, &typeinfo)?;
555 context.dec_depth();
556 Ok(Arc::<dyn Any>::from(boxed))
557 }
558 RefFlag::RefValue => {
559 context.inc_depth()?;
560 let typeinfo = if read_type_info {
561 context.read_any_type_info()?
562 } else {
563 type_info
564 .ok_or_else(|| Error::type_error("No type info found for read Arc<dyn Any>"))?
565 };
566 check_generic_container_type(&typeinfo)?;
568 let boxed = typeinfo
569 .get_harness()
570 .read_polymorphic_data(context, &typeinfo)?;
571 context.dec_depth();
572 let arc: Arc<dyn Any> = Arc::from(boxed);
573 context.ref_reader.store_arc_ref(arc.clone());
574 Ok(arc)
575 }
576 }
577}