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]
41fn is_erased_any_container_type(type_id: TypeId) -> bool {
42 matches!(
43 type_id,
44 TypeId::LIST
45 | TypeId::SET
46 | TypeId::MAP
47 | TypeId::BINARY
48 | TypeId::ARRAY
49 | TypeId::BOOL_ARRAY
50 | TypeId::INT8_ARRAY
51 | TypeId::INT16_ARRAY
52 | TypeId::INT32_ARRAY
53 | TypeId::INT64_ARRAY
54 | TypeId::UINT8_ARRAY
55 | TypeId::UINT16_ARRAY
56 | TypeId::UINT32_ARRAY
57 | TypeId::UINT64_ARRAY
58 | TypeId::FLOAT8_ARRAY
59 | TypeId::FLOAT16_ARRAY
60 | TypeId::BFLOAT16_ARRAY
61 | TypeId::FLOAT32_ARRAY
62 | TypeId::FLOAT64_ARRAY
63 | TypeId::U128_ARRAY
64 | TypeId::INT128_ARRAY
65 | TypeId::USIZE_ARRAY
66 | TypeId::ISIZE_ARRAY
67 )
68}
69
70#[cold]
71#[inline(never)]
72fn unsupported_erased_any_container() -> Error {
73 Error::type_error(
74 "List-, map-, and set-like containers cannot be used as top-level erased Any \
75 payloads via Box<dyn Any>, Rc<dyn Any>, or Arc<dyn Any + Send + Sync>. This \
76 includes Vec<T>, byte and numeric vectors, LinkedList<T>, HashSet<T>, and \
77 HashMap<K, V>. Wrap the container in a registered struct, enum, or union and \
78 use that wrapper as the erased payload.",
79 )
80}
81
82#[cold]
83#[inline(never)]
84fn erased_any_type_info_error(err: Error) -> Error {
85 Error::type_error(format!(
86 "{err}. Erased Any payloads require a registered concrete non-container type. \
87 Top-level list-, map-, and set-like containers such as Vec<T>, LinkedList<T>, \
88 HashSet<T>, and HashMap<K, V> are unsupported; wrap the container in a \
89 registered struct, enum, or union."
90 ))
91}
92
93#[inline]
94pub(crate) fn check_erased_any_payload_type(type_info: &TypeInfo) -> Result<(), Error> {
95 if is_erased_any_container_type(type_info.get_type_id()) {
96 return Err(unsupported_erased_any_container());
97 }
98 Ok(())
99}
100
101#[inline]
102fn get_erased_any_type_info(
103 context: &WriteContext,
104 concrete_type_id: &std::any::TypeId,
105) -> Result<Rc<TypeInfo>, Error> {
106 let type_info = context
107 .get_type_info(concrete_type_id)
108 .map_err(erased_any_type_info_error)?;
109 check_erased_any_payload_type(&type_info)?;
110 Ok(type_info)
111}
112
113#[inline]
114fn write_erased_any_type_info(
115 context: &mut WriteContext,
116 concrete_type_id: std::any::TypeId,
117) -> Result<Rc<TypeInfo>, Error> {
118 let type_info = context
119 .write_any_type_info(TypeId::UNKNOWN as u32, concrete_type_id)
120 .map_err(erased_any_type_info_error)?;
121 check_erased_any_payload_type(&type_info)?;
122 Ok(type_info)
123}
124
125pub fn deserialize_any_box(context: &mut ReadContext) -> Result<Box<dyn Any>, Error> {
127 context.inc_depth()?;
128 let ref_flag = context.reader.read_i8()?;
129 if ref_flag != RefFlag::NotNullValue as i8 {
130 return Err(Error::invalid_ref("Expected NotNullValue for Box<dyn Any>"));
131 }
132 let typeinfo = context.read_any_type_info()?;
133 check_erased_any_payload_type(&typeinfo)?;
134 let result = typeinfo
135 .get_harness()
136 .read_polymorphic_data(context, &typeinfo);
137 context.dec_depth();
138 result
139}
140
141impl ForyDefault for Box<dyn Any> {
142 fn fory_default() -> Self {
143 Box::new(())
144 }
145}
146
147impl Serializer for Box<dyn Any> {
148 fn fory_write(
149 &self,
150 context: &mut WriteContext,
151 ref_mode: RefMode,
152 write_type_info: bool,
153 has_generics: bool,
154 ) -> Result<(), Error> {
155 write_box_any(
156 self.as_ref(),
157 context,
158 ref_mode,
159 write_type_info,
160 has_generics,
161 )
162 }
163
164 fn fory_write_data_generic(
165 &self,
166 context: &mut WriteContext,
167 has_generics: bool,
168 ) -> Result<(), Error> {
169 let concrete_type_id = (**self).type_id();
170 let typeinfo = get_erased_any_type_info(context, &concrete_type_id)?;
171 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
172 serializer_fn(&**self, context, has_generics)
173 }
174
175 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
176 self.fory_write_data_generic(context, false)
177 }
178
179 fn fory_read(
180 context: &mut ReadContext,
181 ref_mode: RefMode,
182 read_type_info: bool,
183 ) -> Result<Self, Error> {
184 read_box_any(context, ref_mode, read_type_info, None)
185 }
186
187 fn fory_read_with_type_info(
188 context: &mut ReadContext,
189 ref_mode: RefMode,
190 type_info: Rc<TypeInfo>,
191 ) -> Result<Self, Error>
192 where
193 Self: Sized + ForyDefault,
194 {
195 read_box_any(context, ref_mode, false, Some(type_info))
196 }
197
198 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
199 Err(Error::not_allowed(
200 "fory_read_data should not be called directly on polymorphic Box<dyn Any> trait object",
201 ))
202 }
203
204 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
205 Err(Error::type_error(
206 "Box<dyn Any> has no static type ID - use fory_type_id_dyn",
207 ))
208 }
209
210 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
211 resolve_registered_type_id(type_resolver, (**self).type_id())
212 }
213
214 fn fory_concrete_type_id(&self) -> std::any::TypeId {
215 (**self).type_id()
216 }
217
218 fn fory_is_polymorphic() -> bool {
219 true
220 }
221
222 fn fory_is_shared_ref() -> bool {
223 false
224 }
225
226 fn fory_static_type_id() -> TypeId {
227 TypeId::UNKNOWN
228 }
229
230 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
231 Ok(())
233 }
234
235 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
236 Ok(())
238 }
239
240 fn as_any(&self) -> &dyn Any {
241 &**self
242 }
243}
244
245pub fn write_box_any(
246 value: &dyn Any,
247 context: &mut WriteContext,
248 ref_mode: RefMode,
249 write_type_info: bool,
250 has_generics: bool,
251) -> Result<(), Error> {
252 if ref_mode != RefMode::None {
253 context.writer.write_i8(RefFlag::NotNullValue as i8);
254 }
255 let concrete_type_id = value.type_id();
256 let typeinfo = if write_type_info {
257 write_erased_any_type_info(context, concrete_type_id)?
258 } else {
259 get_erased_any_type_info(context, &concrete_type_id)?
260 };
261 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
262 serializer_fn(value, context, has_generics)
263}
264
265pub fn read_box_any(
266 context: &mut ReadContext,
267 ref_mode: RefMode,
268 read_type_info: bool,
269 type_info: Option<Rc<TypeInfo>>,
270) -> Result<Box<dyn Any>, Error> {
271 context.inc_depth()?;
272 let ref_flag = if ref_mode != RefMode::None {
273 context.reader.read_i8()?
274 } else {
275 RefFlag::NotNullValue as i8
276 };
277 if ref_flag != RefFlag::NotNullValue as i8 {
278 return Err(Error::invalid_data(
279 "Expected NotNullValue for Box<dyn Any>",
280 ));
281 }
282 let typeinfo = if let Some(type_info) = type_info {
283 type_info
284 } else {
285 ensure!(
286 read_type_info,
287 Error::invalid_data("Type info must be read for Box<dyn Any>")
288 );
289 context.read_any_type_info()?
290 };
291 check_erased_any_payload_type(&typeinfo)?;
292 let result = typeinfo
293 .get_harness()
294 .read_polymorphic_data(context, &typeinfo);
295 context.dec_depth();
296 result
297}
298
299impl ForyDefault for Rc<dyn Any> {
300 fn fory_default() -> Self {
301 Rc::new(())
302 }
303}
304
305impl Serializer for Rc<dyn Any> {
306 fn fory_write(
307 &self,
308 context: &mut WriteContext,
309 ref_mode: RefMode,
310 write_type_info: bool,
311 has_generics: bool,
312 ) -> Result<(), Error> {
313 if ref_mode == RefMode::None
314 || !context
315 .ref_writer
316 .try_write_rc_ref(&mut context.writer, self)
317 {
318 let concrete_type_id: std::any::TypeId = (**self).type_id();
319 let typeinfo = if write_type_info {
320 write_erased_any_type_info(context, concrete_type_id)?
321 } else {
322 get_erased_any_type_info(context, &concrete_type_id)?
323 };
324 let write_data_fn = typeinfo.get_harness().get_write_data_fn();
325 write_data_fn(&**self, context, has_generics)?;
326 }
327 Ok(())
328 }
329
330 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
331 write_dyn_data_generic(self, context, false)
332 }
333
334 fn fory_write_data_generic(
335 &self,
336 context: &mut WriteContext,
337 has_generics: bool,
338 ) -> Result<(), Error> {
339 write_dyn_data_generic(self, context, has_generics)
340 }
341
342 fn fory_read(
343 context: &mut ReadContext,
344 ref_mode: RefMode,
345 read_type_info: bool,
346 ) -> Result<Self, Error> {
347 read_rc_any(context, ref_mode, read_type_info, None)
348 }
349
350 fn fory_read_with_type_info(
351 context: &mut ReadContext,
352 ref_mode: RefMode,
353 type_info: Rc<TypeInfo>,
354 ) -> Result<Self, Error>
355 where
356 Self: Sized + ForyDefault,
357 {
358 read_rc_any(context, ref_mode, false, Some(type_info))
359 }
360
361 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
362 Err(Error::not_allowed(
363 "fory_read_data should not be called directly on polymorphic Rc<dyn Any> trait object",
364 ))
365 }
366
367 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
368 Err(Error::type_error(
369 "Rc<dyn Any> has no static type ID - use fory_type_id_dyn",
370 ))
371 }
372
373 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
374 resolve_registered_type_id(type_resolver, (**self).type_id())
375 }
376
377 fn fory_concrete_type_id(&self) -> std::any::TypeId {
378 (**self).type_id()
379 }
380
381 fn fory_is_shared_ref() -> bool {
382 true
383 }
384 fn fory_is_polymorphic() -> bool {
385 true
386 }
387
388 fn fory_static_type_id() -> TypeId {
389 TypeId::UNKNOWN
390 }
391
392 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
393 Ok(())
395 }
396
397 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
398 Ok(())
400 }
401
402 fn as_any(&self) -> &dyn Any {
403 &**self
404 }
405}
406
407pub fn read_rc_any(
408 context: &mut ReadContext,
409 ref_mode: RefMode,
410 read_type_info: bool,
411 type_info: Option<Rc<TypeInfo>>,
412) -> Result<Rc<dyn Any>, Error> {
413 let ref_flag = if ref_mode != RefMode::None {
414 context.ref_reader.read_ref_flag(&mut context.reader)?
415 } else {
416 RefFlag::NotNullValue
417 };
418 match ref_flag {
419 RefFlag::Null => Err(Error::invalid_ref("Rc<dyn Any> cannot be null")),
420 RefFlag::Ref => {
421 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
422 context
423 .ref_reader
424 .get_rc_ref::<dyn Any>(ref_id)
425 .ok_or_else(|| {
426 Error::invalid_data(format!("Rc<dyn Any> reference {} not found", ref_id))
427 })
428 }
429 RefFlag::NotNullValue => {
430 context.inc_depth()?;
431 let typeinfo = if read_type_info {
432 context.read_any_type_info()?
433 } else {
434 type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
435 };
436 check_erased_any_payload_type(&typeinfo)?;
437 let boxed = typeinfo
438 .get_harness()
439 .read_polymorphic_data(context, &typeinfo)?;
440 context.dec_depth();
441 Ok(Rc::<dyn Any>::from(boxed))
442 }
443 RefFlag::RefValue => {
444 let ref_id = context.ref_reader.reserve_ref_id();
445 context.inc_depth()?;
446 let typeinfo = if read_type_info {
447 context.read_any_type_info()?
448 } else {
449 type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
450 };
451 check_erased_any_payload_type(&typeinfo)?;
452 let boxed = typeinfo
453 .get_harness()
454 .read_polymorphic_data(context, &typeinfo)?;
455 context.dec_depth();
456 let rc: Rc<dyn Any> = Rc::from(boxed);
457 context.ref_reader.store_rc_ref_at(ref_id, rc.clone());
458 Ok(rc)
459 }
460 }
461}
462
463impl ForyDefault for Arc<dyn Any + Send + Sync> {
464 fn fory_default() -> Self {
465 Arc::new(())
466 }
467}
468
469impl Serializer for Arc<dyn Any + Send + Sync> {
470 fn fory_write(
471 &self,
472 context: &mut WriteContext,
473 ref_mode: RefMode,
474 write_type_info: bool,
475 has_generics: bool,
476 ) -> Result<(), Error> {
477 if ref_mode == RefMode::None
478 || !context
479 .ref_writer
480 .try_write_arc_ref(&mut context.writer, self)
481 {
482 let value: &dyn Any = self.as_ref();
483 let concrete_type_id: std::any::TypeId = value.type_id();
484 let typeinfo = if write_type_info {
485 write_erased_any_type_info(context, concrete_type_id)?
486 } else {
487 get_erased_any_type_info(context, &concrete_type_id)?
488 };
489 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
490 serializer_fn(value, context, has_generics)?;
491 }
492 Ok(())
493 }
494
495 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
496 write_dyn_data_generic(self, context, false)
497 }
498
499 fn fory_write_data_generic(
500 &self,
501 context: &mut WriteContext,
502 has_generics: bool,
503 ) -> Result<(), Error> {
504 write_dyn_data_generic(self, context, has_generics)
505 }
506
507 fn fory_read(
508 context: &mut ReadContext,
509 ref_mode: RefMode,
510 read_type_info: bool,
511 ) -> Result<Self, Error> {
512 read_arc_any(context, ref_mode, read_type_info, None)
513 }
514
515 fn fory_read_with_type_info(
516 context: &mut ReadContext,
517 ref_mode: RefMode,
518 type_info: Rc<TypeInfo>,
519 ) -> Result<Self, Error>
520 where
521 Self: Sized + ForyDefault,
522 {
523 read_arc_any(context, ref_mode, false, Some(type_info))
524 }
525
526 fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
527 Err(Error::not_allowed(
528 "fory_read_data should not be called directly on polymorphic Arc<dyn Any + Send + Sync> trait object"
529 ))
530 }
531
532 fn fory_get_type_id(_type_resolver: &TypeResolver) -> Result<TypeId, Error> {
533 Err(Error::type_error(
534 "Arc<dyn Any + Send + Sync> has no static type ID - use fory_type_id_dyn",
535 ))
536 }
537
538 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
539 resolve_registered_type_id(type_resolver, self.as_ref().type_id())
540 }
541
542 fn fory_concrete_type_id(&self) -> std::any::TypeId {
543 self.as_ref().type_id()
544 }
545
546 fn fory_is_polymorphic() -> bool {
547 true
548 }
549
550 fn fory_is_shared_ref() -> bool {
551 true
552 }
553 fn fory_static_type_id() -> TypeId {
554 TypeId::UNKNOWN
555 }
556
557 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
558 Ok(())
560 }
561
562 fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
563 Ok(())
565 }
566
567 fn fory_read_data_as_send_sync_any(
568 context: &mut ReadContext,
569 ) -> Result<Box<dyn Any + Send + Sync>, Error>
570 where
571 Self: Sized + ForyDefault,
572 {
573 Ok(crate::serializer::box_send_sync(read_arc_any(
574 context,
575 RefMode::None,
576 true,
577 None,
578 )?))
579 }
580
581 fn as_any(&self) -> &dyn Any {
582 self.as_ref()
583 }
584}
585
586pub fn read_arc_any(
587 context: &mut ReadContext,
588 ref_mode: RefMode,
589 read_type_info: bool,
590 type_info: Option<Rc<TypeInfo>>,
591) -> Result<Arc<dyn Any + Send + Sync>, Error> {
592 let ref_flag = if ref_mode != RefMode::None {
593 context.ref_reader.read_ref_flag(&mut context.reader)?
594 } else {
595 RefFlag::NotNullValue
596 };
597 match ref_flag {
598 RefFlag::Null => Err(Error::invalid_ref(
599 "Arc<dyn Any + Send + Sync> cannot be null",
600 )),
601 RefFlag::Ref => {
602 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
603 context
604 .ref_reader
605 .get_arc_ref::<dyn Any + Send + Sync>(ref_id)
606 .ok_or_else(|| {
607 Error::invalid_data(format!(
608 "Arc<dyn Any + Send + Sync> reference {} not found",
609 ref_id
610 ))
611 })
612 }
613 RefFlag::NotNullValue => {
614 context.inc_depth()?;
615 let typeinfo = if read_type_info {
616 context.read_any_type_info()?
617 } else {
618 type_info.ok_or_else(|| {
619 Error::type_error("No type info found for read Arc<dyn Any + Send + Sync>")
620 })?
621 };
622 check_erased_any_payload_type(&typeinfo)?;
623 let boxed = typeinfo
624 .get_harness()
625 .read_polymorphic_data_as_send_sync_any(context, &typeinfo)?;
626 context.dec_depth();
627 Ok(Arc::<dyn Any + Send + Sync>::from(boxed))
628 }
629 RefFlag::RefValue => {
630 let ref_id = context.ref_reader.reserve_ref_id();
631 context.inc_depth()?;
632 let typeinfo = if read_type_info {
633 context.read_any_type_info()?
634 } else {
635 type_info.ok_or_else(|| {
636 Error::type_error("No type info found for read Arc<dyn Any + Send + Sync>")
637 })?
638 };
639 check_erased_any_payload_type(&typeinfo)?;
640 let boxed = typeinfo
641 .get_harness()
642 .read_polymorphic_data_as_send_sync_any(context, &typeinfo)?;
643 context.dec_depth();
644 let arc: Arc<dyn Any + Send + Sync> = Arc::from(boxed);
645 context.ref_reader.store_arc_ref_at(ref_id, arc.clone());
646 Ok(arc)
647 }
648 }
649}