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