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