1use crate::context::{ReadContext, WriteContext};
22use crate::ensure;
23use crate::error::Error;
24use crate::resolver::{TypeInfo, TypeResolver};
25use crate::serializer::{ForyDefault, Serializer};
26use crate::RefFlag;
27use crate::RefMode;
28use crate::TypeId;
29use std::rc::Rc;
30
31#[macro_export]
33macro_rules! downcast_and_serialize {
34 ($any_ref:expr, $context:expr, $trait_name:ident, $($impl_type:ty),+) => {{
35 $(
36 if $any_ref.type_id() == std::any::TypeId::of::<$impl_type>() {
37 if let Some(concrete) = $any_ref.downcast_ref::<$impl_type>() {
38 concrete.fory_write_data($context)?;
39 return Ok(());
40 }
41 }
42 )*
43 return Err(fory_core::Error::type_error(format!("Failed to downcast to any registered type for trait {}", stringify!($trait_name))));
44 }};
45}
46
47#[macro_export]
104macro_rules! register_trait_type {
105 ($trait_name:ident, $($impl_type:ty),+ $(,)?) => {
106 impl $crate::serializer::ForyDefault for Box<dyn $trait_name> {
109 fn fory_default() -> Self {
110 Box::new(<register_trait_type!(@first_type $($impl_type),+) as $crate::serializer::ForyDefault>::fory_default())
111 }
112 }
113 $crate::generate_box_trait_codec!($trait_name);
114
115 $crate::generate_smart_pointer_wrapper!(
117 std::rc::Rc,
118 Rc,
119 std::rc::Rc::get_mut,
120 $trait_name,
121 try_write_rc_ref,
122 get_rc_ref,
123 store_rc_ref,
124 $($impl_type),+
125 );
126 $crate::generate_smart_pointer_codec!(std::rc::Rc, Rc, $trait_name);
127
128 $crate::generate_smart_pointer_wrapper!(
130 std::sync::Arc,
131 Arc,
132 std::sync::Arc::get_mut,
133 $trait_name,
134 try_write_arc_ref,
135 get_arc_ref,
136 store_arc_ref,
137 $($impl_type),+
138 );
139 $crate::generate_smart_pointer_codec!(std::sync::Arc, Arc, $trait_name);
140
141 impl fory_core::Serializer for Box<dyn $trait_name> {
143 #[inline(always)]
144 fn fory_write(&self, context: &mut fory_core::WriteContext, ref_mode: fory_core::RefMode, write_type_info: bool, has_generics: bool) -> Result<(), fory_core::Error> {
145 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
146 fory_core::serializer::write_box_any(any_ref, context, ref_mode, write_type_info, has_generics)
147 }
148
149 #[inline(always)]
150 fn fory_write_data(&self, context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
151 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
152 fory_core::serializer::write_box_any(any_ref, context, fory_core::RefMode::None, false, false)
153 }
154
155 #[inline(always)]
156 fn fory_write_data_generic(&self, context: &mut fory_core::WriteContext, has_generics: bool) -> Result<(), fory_core::Error> {
157 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
158 fory_core::serializer::write_box_any(any_ref, context, fory_core::RefMode::None, false, has_generics)
159 }
160
161 #[inline(always)]
162 fn fory_type_id_dyn(&self, type_resolver: &fory_core::resolver::TypeResolver) -> Result<fory_core::TypeId, fory_core::Error> {
163 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
164 let concrete_type_id = any_ref.type_id();
165 type_resolver
166 .get_fory_type_id(concrete_type_id)
167 .ok_or_else(|| fory_core::Error::type_error("Type not registered for trait object"))
168 }
169
170 #[inline(always)]
171 fn fory_is_polymorphic() -> bool {
172 true
173 }
174
175 fn fory_write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
176 $crate::not_allowed!("fory_write_type_info should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
177 }
178
179 fn fory_read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
180 $crate::not_allowed!("fory_read_type_info should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
181 }
182
183 fn fory_read(context: &mut fory_core::ReadContext, ref_mode: fory_core::RefMode, read_type_info: bool) -> Result<Self, fory_core::Error> {
184 let boxed_any = fory_core::serializer::read_box_any(context, ref_mode, read_type_info, None)?;
185 $(
186 if boxed_any.is::<$impl_type>() {
187 let concrete = boxed_any.downcast::<$impl_type>()
188 .map_err(|_| fory_core::Error::type_error("Downcast failed"))?;
189 let ptr = Box::new(*concrete);
190 return Ok(Self::from(ptr));
191 }
192 )*
193 Err(fory_core::Error::type_error(
194 format!("Deserialized type does not implement trait {}", stringify!($trait_name))
195 ))
196 }
197
198 fn fory_read_with_type_info(
199 context: &mut fory_core::ReadContext,
200 ref_mode: fory_core::RefMode,
201 type_info: std::rc::Rc<fory_core::TypeInfo>,
202 ) -> Result<Self, fory_core::Error>
203 where
204 Self: Sized + fory_core::ForyDefault,
205 {
206 let boxed_any = fory_core::serializer::read_box_any(context, ref_mode, false, Some(type_info))?;
207 $(
208 if boxed_any.is::<$impl_type>() {
209 let concrete = boxed_any.downcast::<$impl_type>()
210 .map_err(|_| fory_core::Error::type_error("Downcast failed"))?;
211 let ptr = Box::new(*concrete);
212 return Ok(Self::from(ptr));
213 }
214 )*
215 Err(fory_core::Error::type_error(
216 format!("Deserialized type does not implement trait {}", stringify!($trait_name))
217 ))
218 }
219
220 fn fory_read_data(_context: &mut fory_core::ReadContext) -> Result<Self, fory_core::Error> {
221 $crate::not_allowed!("fory_read_data should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
224 }
225
226 fn fory_get_type_id(_type_resolver: &fory_core::resolver::TypeResolver) -> Result<fory_core::TypeId, fory_core::Error> {
227 $crate::not_allowed!("fory_get_type_id should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
228 }
229
230 #[inline(always)]
231 fn fory_static_type_id() -> fory_core::TypeId {
232 fory_core::TypeId::UNKNOWN
233 }
234
235 #[inline(always)]
236 fn fory_reserved_space() -> usize {
237 $crate::type_id::SIZE_OF_REF_AND_TYPE
238 }
239
240 #[inline(always)]
241 fn fory_concrete_type_id(&self) -> std::any::TypeId {
242 <dyn $trait_name as fory_core::Serializer>::as_any(&**self).type_id()
243 }
244
245 #[inline(always)]
246 fn as_any(&self) -> &dyn std::any::Any {
247 <dyn $trait_name as fory_core::Serializer>::as_any(&**self)
248 }
249 }
250 };
251
252 (@first_type $first_type:ty $(, $rest:ty)*) => {
254 $first_type
255 };
256}
257
258#[macro_export]
261macro_rules! generate_smart_pointer_wrapper {
262 ($ptr_path:path, $ptr_name:ident, $get_mut:path, $trait_name:ident, $try_write_ref:ident, $get_ref:ident, $store_ref:ident, $($impl_type:ty),+ $(,)?) => {
263 $crate::paste::paste! {
264 #[derive(Clone)]
265 pub(crate) struct [<$trait_name $ptr_name>]($ptr_path<dyn $trait_name>);
266
267 impl [<$trait_name $ptr_name>] {
268 pub(crate) fn new(inner: $ptr_path<dyn $trait_name>) -> Self {
269 Self(inner)
270 }
271
272 pub(crate) fn into_inner(self) -> $ptr_path<dyn $trait_name> {
273 self.0
274 }
275
276 pub(crate) fn unwrap(self) -> $ptr_path<dyn $trait_name> {
277 self.0
278 }
279
280 pub(crate) fn as_ref(&self) -> &dyn $trait_name {
281 &*self.0
282 }
283 }
284
285 impl std::ops::Deref for [<$trait_name $ptr_name>] {
286 type Target = dyn $trait_name;
287
288 fn deref(&self) -> &Self::Target {
289 &*self.0
290 }
291 }
292
293 impl std::ops::DerefMut for [<$trait_name $ptr_name>] {
294 fn deref_mut(&mut self) -> &mut Self::Target {
295 $get_mut(&mut self.0)
296 .expect(&format!("Cannot get mutable reference to {} with multiple strong references", stringify!($ptr_name)))
297 }
298 }
299
300 impl From<$ptr_path<dyn $trait_name>> for [<$trait_name $ptr_name>] {
301 fn from(ptr: $ptr_path<dyn $trait_name>) -> Self {
302 Self::new(ptr)
303 }
304 }
305
306 impl From<[<$trait_name $ptr_name>]> for $ptr_path<dyn $trait_name> {
307 fn from(wrapper: [<$trait_name $ptr_name>]) -> Self {
308 wrapper.into_inner()
309 }
310 }
311
312 impl $crate::serializer::ForyDefault for [<$trait_name $ptr_name>] {
313 fn fory_default() -> Self {
314 Self($ptr_path::new(<$crate::register_trait_type!(@first_type $($impl_type),+) as $crate::serializer::ForyDefault>::fory_default()))
315 }
316 }
317
318 impl std::fmt::Debug for [<$trait_name $ptr_name>] {
319 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
321 $(
322 if let Some(concrete) = any_obj.downcast_ref::<$impl_type>() {
323 return write!(f, concat!(stringify!($trait_name), stringify!($ptr_name), "({:?})"), concrete);
324 }
325 )*
326 write!(f, concat!(stringify!($trait_name), stringify!($ptr_name), "({:p})"), &*self.0)
327 }
328 }
329
330 $crate::impl_smart_pointer_serializer!(
331 [<$trait_name $ptr_name>],
332 $ptr_path<dyn $trait_name>,
333 $ptr_path::new,
334 $trait_name,
335 $try_write_ref,
336 $get_ref,
337 $store_ref,
338 $($impl_type),+
339 );
340 }
341 };
342}
343
344#[macro_export]
345macro_rules! generate_smart_pointer_codec {
346 ($ptr_path:path, $ptr_name:ident, $trait_name:ident) => {
347 $crate::paste::paste! {
348 pub(crate) struct [<$trait_name $ptr_name Codec>]<const NULLABLE: bool, const TRACK_REF: bool>;
349
350 impl<const NULLABLE: bool, const TRACK_REF: bool>
351 fory_core::serializer::codec::Codec<$ptr_path<dyn $trait_name>>
352 for [<$trait_name $ptr_name Codec>]<NULLABLE, TRACK_REF>
353 {
354 #[inline(always)]
355 fn field_type(
356 _type_resolver: &fory_core::resolver::TypeResolver,
357 ) -> Result<fory_core::meta::FieldType, fory_core::Error> {
358 Ok(fory_core::meta::FieldType::new_with_ref(
359 fory_core::type_id::TypeId::UNKNOWN as u32,
360 NULLABLE,
361 TRACK_REF,
362 Vec::new(),
363 ))
364 }
365
366 #[inline(always)]
367 fn reserved_space() -> usize {
368 <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_reserved_space()
369 + fory_core::type_id::SIZE_OF_REF_AND_TYPE
370 }
371
372 #[inline(always)]
373 fn write_field(
374 value: &$ptr_path<dyn $trait_name>,
375 context: &mut fory_core::WriteContext,
376 ) -> Result<(), fory_core::Error> {
377 let wrapper = [<$trait_name $ptr_name>]::from(value.clone());
378 <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_write(
379 &wrapper,
380 context,
381 if TRACK_REF {
382 fory_core::RefMode::Tracking
383 } else if NULLABLE {
384 fory_core::RefMode::NullOnly
385 } else {
386 fory_core::RefMode::None
387 },
388 true,
389 false,
390 )
391 }
392
393 #[inline(always)]
394 fn read_field(
395 context: &mut fory_core::ReadContext,
396 ) -> Result<$ptr_path<dyn $trait_name>, fory_core::Error> {
397 Self::read_with_mode(
398 context,
399 if TRACK_REF {
400 fory_core::RefMode::Tracking
401 } else if NULLABLE {
402 fory_core::RefMode::NullOnly
403 } else {
404 fory_core::RefMode::None
405 },
406 true,
407 )
408 }
409
410 #[inline(always)]
411 fn write_data(
412 value: &$ptr_path<dyn $trait_name>,
413 context: &mut fory_core::WriteContext,
414 ) -> Result<(), fory_core::Error> {
415 let wrapper = [<$trait_name $ptr_name>]::from(value.clone());
416 <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_write_data(
417 &wrapper,
418 context,
419 )
420 }
421
422 #[inline(always)]
423 fn read_data(
424 context: &mut fory_core::ReadContext,
425 ) -> Result<$ptr_path<dyn $trait_name>, fory_core::Error> {
426 Self::read_with_mode(context, fory_core::RefMode::None, true)
427 }
428
429 #[inline(always)]
430 fn read_field_with_type(
431 context: &mut fory_core::ReadContext,
432 remote_field_type: &fory_core::meta::FieldType,
433 ) -> Result<$ptr_path<dyn $trait_name>, fory_core::Error> {
434 Self::read_with_mode(
435 context,
436 fory_core::serializer::codec::field_ref_mode(remote_field_type),
437 true,
438 )
439 }
440
441 #[inline(always)]
442 fn write_with_mode(
443 value: &$ptr_path<dyn $trait_name>,
444 context: &mut fory_core::WriteContext,
445 ref_mode: fory_core::RefMode,
446 write_type_info: bool,
447 has_generics: bool,
448 ) -> Result<(), fory_core::Error> {
449 let wrapper = [<$trait_name $ptr_name>]::from(value.clone());
450 <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_write(
451 &wrapper,
452 context,
453 ref_mode,
454 write_type_info,
455 has_generics,
456 )
457 }
458
459 #[inline(always)]
460 fn read_with_mode(
461 context: &mut fory_core::ReadContext,
462 ref_mode: fory_core::RefMode,
463 read_type_info: bool,
464 ) -> Result<$ptr_path<dyn $trait_name>, fory_core::Error> {
465 let wrapper = <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_read(
466 context,
467 ref_mode,
468 read_type_info,
469 )?;
470 Ok($ptr_path::<dyn $trait_name>::from(wrapper))
471 }
472
473 #[inline(always)]
474 fn read_with_type_info(
475 context: &mut fory_core::ReadContext,
476 ref_mode: fory_core::RefMode,
477 type_info: std::rc::Rc<fory_core::TypeInfo>,
478 ) -> Result<$ptr_path<dyn $trait_name>, fory_core::Error> {
479 let wrapper =
480 <[<$trait_name $ptr_name>] as fory_core::Serializer>::fory_read_with_type_info(
481 context,
482 ref_mode,
483 type_info,
484 )?;
485 Ok($ptr_path::<dyn $trait_name>::from(wrapper))
486 }
487
488 #[inline(always)]
489 fn default_value() -> $ptr_path<dyn $trait_name> {
490 $ptr_path::<dyn $trait_name>::from(
491 <[<$trait_name $ptr_name>] as fory_core::ForyDefault>::fory_default(),
492 )
493 }
494
495 #[inline(always)]
496 fn write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
497 Ok(())
498 }
499
500 #[inline(always)]
501 fn read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
502 Ok(())
503 }
504
505 #[inline(always)]
506 fn static_type_id() -> fory_core::TypeId {
507 fory_core::TypeId::UNKNOWN
508 }
509
510 #[inline(always)]
511 fn is_polymorphic() -> bool {
512 true
513 }
514
515 #[inline(always)]
516 fn is_shared_ref() -> bool {
517 true
518 }
519
520 #[inline(always)]
521 fn concrete_type_id(value: &$ptr_path<dyn $trait_name>) -> std::any::TypeId {
522 <dyn $trait_name as fory_core::Serializer>::as_any(&**value).type_id()
523 }
524 }
525 }
526 };
527}
528
529#[macro_export]
530macro_rules! generate_box_trait_codec {
531 ($trait_name:ident) => {
532 $crate::paste::paste! {
533 pub(crate) struct [<$trait_name BoxCodec>]<const NULLABLE: bool, const TRACK_REF: bool>;
534
535 impl<const NULLABLE: bool, const TRACK_REF: bool>
536 fory_core::serializer::codec::Codec<Box<dyn $trait_name>>
537 for [<$trait_name BoxCodec>]<NULLABLE, TRACK_REF>
538 {
539 #[inline(always)]
540 fn field_type(
541 _type_resolver: &fory_core::resolver::TypeResolver,
542 ) -> Result<fory_core::meta::FieldType, fory_core::Error> {
543 Ok(fory_core::meta::FieldType::new_with_ref(
544 fory_core::type_id::TypeId::UNKNOWN as u32,
545 NULLABLE,
546 TRACK_REF,
547 Vec::new(),
548 ))
549 }
550
551 #[inline(always)]
552 fn reserved_space() -> usize {
553 <Box<dyn $trait_name> as fory_core::Serializer>::fory_reserved_space()
554 + fory_core::type_id::SIZE_OF_REF_AND_TYPE
555 }
556
557 #[inline(always)]
558 fn write_field(
559 value: &Box<dyn $trait_name>,
560 context: &mut fory_core::WriteContext,
561 ) -> Result<(), fory_core::Error> {
562 <Box<dyn $trait_name> as fory_core::Serializer>::fory_write(
563 value,
564 context,
565 if TRACK_REF {
566 fory_core::RefMode::Tracking
567 } else if NULLABLE {
568 fory_core::RefMode::NullOnly
569 } else {
570 fory_core::RefMode::None
571 },
572 true,
573 false,
574 )
575 }
576
577 #[inline(always)]
578 fn read_field(
579 context: &mut fory_core::ReadContext,
580 ) -> Result<Box<dyn $trait_name>, fory_core::Error> {
581 Self::read_with_mode(
582 context,
583 if TRACK_REF {
584 fory_core::RefMode::Tracking
585 } else if NULLABLE {
586 fory_core::RefMode::NullOnly
587 } else {
588 fory_core::RefMode::None
589 },
590 true,
591 )
592 }
593
594 #[inline(always)]
595 fn write_data(
596 value: &Box<dyn $trait_name>,
597 context: &mut fory_core::WriteContext,
598 ) -> Result<(), fory_core::Error> {
599 <Box<dyn $trait_name> as fory_core::Serializer>::fory_write_data(
600 value,
601 context,
602 )
603 }
604
605 #[inline(always)]
606 fn read_data(
607 context: &mut fory_core::ReadContext,
608 ) -> Result<Box<dyn $trait_name>, fory_core::Error> {
609 Self::read_with_mode(context, fory_core::RefMode::None, true)
610 }
611
612 #[inline(always)]
613 fn read_field_with_type(
614 context: &mut fory_core::ReadContext,
615 remote_field_type: &fory_core::meta::FieldType,
616 ) -> Result<Box<dyn $trait_name>, fory_core::Error> {
617 Self::read_with_mode(
618 context,
619 fory_core::serializer::codec::field_ref_mode(remote_field_type),
620 true,
621 )
622 }
623
624 #[inline(always)]
625 fn write_with_mode(
626 value: &Box<dyn $trait_name>,
627 context: &mut fory_core::WriteContext,
628 ref_mode: fory_core::RefMode,
629 write_type_info: bool,
630 has_generics: bool,
631 ) -> Result<(), fory_core::Error> {
632 <Box<dyn $trait_name> as fory_core::Serializer>::fory_write(
633 value,
634 context,
635 ref_mode,
636 write_type_info,
637 has_generics,
638 )
639 }
640
641 #[inline(always)]
642 fn read_with_mode(
643 context: &mut fory_core::ReadContext,
644 ref_mode: fory_core::RefMode,
645 read_type_info: bool,
646 ) -> Result<Box<dyn $trait_name>, fory_core::Error> {
647 <Box<dyn $trait_name> as fory_core::Serializer>::fory_read(
648 context,
649 ref_mode,
650 read_type_info,
651 )
652 }
653
654 #[inline(always)]
655 fn read_with_type_info(
656 context: &mut fory_core::ReadContext,
657 ref_mode: fory_core::RefMode,
658 type_info: std::rc::Rc<fory_core::TypeInfo>,
659 ) -> Result<Box<dyn $trait_name>, fory_core::Error> {
660 <Box<dyn $trait_name> as fory_core::Serializer>::fory_read_with_type_info(
661 context,
662 ref_mode,
663 type_info,
664 )
665 }
666
667 #[inline(always)]
668 fn default_value() -> Box<dyn $trait_name> {
669 <Box<dyn $trait_name> as fory_core::ForyDefault>::fory_default()
670 }
671
672 #[inline(always)]
673 fn write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
674 Ok(())
675 }
676
677 #[inline(always)]
678 fn read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
679 Ok(())
680 }
681
682 #[inline(always)]
683 fn static_type_id() -> fory_core::TypeId {
684 fory_core::TypeId::UNKNOWN
685 }
686
687 #[inline(always)]
688 fn is_polymorphic() -> bool {
689 true
690 }
691
692 #[inline(always)]
693 fn concrete_type_id(value: &Box<dyn $trait_name>) -> std::any::TypeId {
694 <dyn $trait_name as fory_core::Serializer>::as_any(&**value).type_id()
695 }
696 }
697 }
698 };
699}
700
701#[macro_export]
704macro_rules! read_ptr_trait_object {
705 ($context:expr, $ref_mode:expr, $read_type_info:expr, $type_info:expr, $pointer_type:ty, $trait_name:ident, $constructor_expr:expr, $get_ref:ident, $store_ref:ident, $($impl_type:ty),+) => {{
706 let ref_flag = if $ref_mode != fory_core::RefMode::None {
707 $context.ref_reader.read_ref_flag(&mut $context.reader)?
708 } else {
709 fory_core::RefFlag::NotNullValue
710 };
711 match ref_flag {
712 fory_core::RefFlag::Null => Err(fory_core::Error::invalid_ref(format!("smart pointer to dyn {} cannot be null", stringify!($trait_name)))),
713 fory_core::RefFlag::Ref => {
714 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
715 let ptr_ref = $context.ref_reader.$get_ref::<dyn $trait_name>(ref_id)
716 .ok_or_else(|| fory_core::Error::invalid_data(format!("dyn {} reference {} not found", stringify!($trait_name), ref_id)))?;
717 Ok(Self::from(ptr_ref))
718 }
719 fory_core::RefFlag::NotNullValue => {
720 $context.inc_depth()?;
721 let typeinfo = if $read_type_info {
722 $context.read_any_type_info()?
723 } else {
724 $type_info.ok_or_else(|| fory_core::Error::type_error("No type info found for read"))?
725 };
726 let fory_type_id = typeinfo.get_type_id();
727 let user_type_id = typeinfo.get_user_type_id();
728 let registered_by_name = typeinfo.is_registered_by_name();
729 let namespace = typeinfo.get_namespace();
730 let type_name = typeinfo.get_type_name();
731 let matches_type = |local_info: &fory_core::TypeInfo| -> bool {
732 if registered_by_name {
733 local_info.is_registered_by_name()
734 && local_info.get_namespace().original == namespace.original
735 && local_info.get_type_name().original == type_name.original
736 } else if user_type_id != u32::MAX {
737 local_info.get_user_type_id() == user_type_id
738 } else {
739 local_info.get_type_id() == fory_type_id
740 }
741 };
742 $(
743 if let Ok(local_info) = $context.get_type_resolver().get_type_info(&std::any::TypeId::of::<$impl_type>()) {
744 if matches_type(&local_info) {
745 let concrete_obj = <$impl_type as fory_core::Serializer>::fory_read_data($context)?;
746 $context.dec_depth();
747 let ptr = $constructor_expr(concrete_obj) as $pointer_type;
748 return Ok(Self::from(ptr));
749 }
750 }
751 )*
752 $context.dec_depth();
753 Err(fory_core::Error::type_error(format!(
754 "Type ID {} not registered for trait {}",
755 fory_type_id as u32,
756 stringify!($trait_name)
757 )))
758 }
759 fory_core::RefFlag::RefValue => {
760 $context.inc_depth()?;
761 let typeinfo = if $read_type_info {
762 $context.read_any_type_info()?
763 } else {
764 $type_info.ok_or_else(|| fory_core::Error::type_error("No type info found for read"))?
765 };
766 let fory_type_id = typeinfo.get_type_id();
767 let user_type_id = typeinfo.get_user_type_id();
768 let registered_by_name = typeinfo.is_registered_by_name();
769 let namespace = typeinfo.get_namespace();
770 let type_name = typeinfo.get_type_name();
771 let matches_type = |local_info: &fory_core::TypeInfo| -> bool {
772 if registered_by_name {
773 local_info.is_registered_by_name()
774 && local_info.get_namespace().original == namespace.original
775 && local_info.get_type_name().original == type_name.original
776 } else if user_type_id != u32::MAX {
777 local_info.get_user_type_id() == user_type_id
778 } else {
779 local_info.get_type_id() == fory_type_id
780 }
781 };
782 $(
783 if let Ok(local_info) = $context.get_type_resolver().get_type_info(&std::any::TypeId::of::<$impl_type>()) {
784 if matches_type(&local_info) {
785 let concrete_obj = <$impl_type as fory_core::Serializer>::fory_read_data($context)?;
786 $context.dec_depth();
787 let ptr = $constructor_expr(concrete_obj) as $pointer_type;
788 let wrapper = Self::from(ptr.clone());
789 $context.ref_reader.$store_ref(ptr);
790 return Ok(wrapper);
791 }
792 }
793 )*
794 $context.dec_depth();
795 Err(fory_core::Error::type_error(format!(
796 "Type ID {} not registered for trait {}",
797 fory_type_id as u32,
798 stringify!($trait_name)
799 )))
800 }
801 }
802 }};
803}
804
805#[macro_export]
807macro_rules! impl_smart_pointer_serializer {
808 ($wrapper_name:ident, $pointer_type:ty, $constructor_expr:expr, $trait_name:ident, $try_write_ref:ident, $get_ref:ident, $store_ref:ident, $($impl_type:ty),+) => {
809 impl fory_core::Serializer for $wrapper_name {
810 fn fory_write(&self, context: &mut fory_core::WriteContext, ref_mode: fory_core::RefMode, write_type_info: bool, has_generics: bool) -> Result<(), fory_core::Error> {
811 if ref_mode == fory_core::RefMode::None || !context.ref_writer.$try_write_ref(&mut context.writer, &self.0) {
812 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
813 let concrete_type_id = any_obj.type_id();
814 let typeinfo = if write_type_info {
815 context.write_any_type_info(fory_core::TypeId::UNKNOWN as u32, concrete_type_id)?
816 } else {
817 context.get_type_info(&concrete_type_id)?
818 };
819 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
820 serializer_fn(any_obj, context, has_generics)?;
821 }
822 Ok(())
823 }
824
825 fn fory_write_data(&self, context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
826 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
827 $crate::downcast_and_serialize!(any_obj, context, $trait_name, $($impl_type),+)
828 }
829
830 fn fory_read(context: &mut fory_core::ReadContext, ref_mode: fory_core::RefMode, read_type_info: bool) -> Result<Self, fory_core::Error> {
831 $crate::read_ptr_trait_object!(
832 context,
833 ref_mode,
834 read_type_info,
835 None,
836 $pointer_type,
837 $trait_name,
838 $constructor_expr,
839 $get_ref,
840 $store_ref,
841 $($impl_type),+
842 )
843 }
844
845 fn fory_read_with_type_info(context: &mut fory_core::ReadContext, ref_mode: fory_core::RefMode, type_info: std::rc::Rc<fory_core::TypeInfo>) -> Result<Self, fory_core::Error> {
846 $crate::read_ptr_trait_object!(
847 context,
848 ref_mode,
849 false,
850 Some(type_info),
851 $pointer_type,
852 $trait_name,
853 $constructor_expr,
854 $get_ref,
855 $store_ref,
856 $($impl_type),+
857 )
858 }
859
860 fn fory_read_data(context: &mut fory_core::ReadContext) -> Result<Self, fory_core::Error> {
861 $crate::not_allowed!("fory_read_data should not be called directly on polymorphic {}<dyn {}> trait object", stringify!($ptr_path), stringify!($trait_name))
862 }
863
864 #[inline(always)]
865 fn fory_get_type_id(_type_resolver: &fory_core::resolver::TypeResolver) -> Result<fory_core::TypeId, fory_core::Error> {
866 Ok(fory_core::TypeId::STRUCT)
867 }
868
869 #[inline(always)]
870 fn fory_static_type_id() -> fory_core::TypeId {
871 fory_core::TypeId::UNKNOWN
872 }
873
874 #[inline(always)]
875 fn fory_write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
876 Ok(())
877 }
878
879 #[inline(always)]
880 fn fory_read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
881 Ok(())
882 }
883
884 #[inline(always)]
885 fn fory_is_polymorphic() -> bool {
886 true
887 }
888
889 #[inline(always)]
890 fn fory_is_shared_ref() -> bool {
891 true
892 }
893
894 #[inline(always)]
895 fn fory_type_id_dyn(&self, type_resolver: &fory_core::resolver::TypeResolver) -> Result<fory_core::TypeId, fory_core::Error> {
896 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
897 let concrete_type_id = any_obj.type_id();
898 type_resolver
899 .get_fory_type_id(concrete_type_id)
900 .ok_or_else(|| fory_core::Error::type_error("Type not registered for trait object"))
901 }
902
903 #[inline(always)]
904 fn fory_concrete_type_id(&self) -> std::any::TypeId {
905 <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0).type_id()
906 }
907
908 #[inline(always)]
909 fn as_any(&self) -> &dyn std::any::Any {
910 <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0)
911 }
912 }
913 };
914}
915
916#[macro_export]
921macro_rules! wrap_rc {
922 ($field:expr, $trait_name:ident) => {
923 $crate::paste::paste! {
924 [<$trait_name Rc>]::from($field)
925 }
926 };
927}
928
929#[macro_export]
931macro_rules! unwrap_rc {
932 ($wrapper:expr, $trait_name:ident) => {
933 std::rc::Rc::<dyn $trait_name>::from($wrapper)
934 };
935}
936
937#[macro_export]
939macro_rules! wrap_arc {
940 ($field:expr, $trait_name:ident) => {
941 $crate::paste::paste! {
942 [<$trait_name Arc>]::from($field)
943 }
944 };
945}
946
947#[macro_export]
949macro_rules! wrap_vec_rc {
950 ($vec:expr, $trait_name:ident) => {
951 $crate::paste::paste! {
952 $vec.into_iter().map(|item| [<$trait_name Rc>]::from(item)).collect()
953 }
954 };
955}
956
957impl Default for Box<dyn Serializer> {
958 fn default() -> Self {
959 Box::new(0)
960 }
961}
962
963impl ForyDefault for Box<dyn Serializer> {
964 fn fory_default() -> Self {
965 Box::new(0)
966 }
967}
968
969impl Serializer for Box<dyn Serializer> {
970 #[inline(always)]
971 fn fory_concrete_type_id(&self) -> std::any::TypeId {
972 (**self).fory_concrete_type_id()
973 }
974
975 fn fory_write(
976 &self,
977 context: &mut WriteContext,
978 ref_mode: RefMode,
979 write_type_info: bool,
980 has_generics: bool,
981 ) -> Result<(), Error> {
982 if ref_mode != RefMode::None {
983 context.writer.write_i8(RefFlag::NotNullValue as i8);
984 }
985 let fory_type_id_dyn = self.fory_type_id_dyn(context.get_type_resolver())?;
986 let concrete_type_id = (**self).fory_concrete_type_id();
987 if write_type_info {
988 context.write_any_type_info(fory_type_id_dyn as u32, concrete_type_id)?;
989 };
990 self.fory_write_data_generic(context, has_generics)
991 }
992
993 #[inline(always)]
994 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
995 self.fory_write_data_generic(context, false)
996 }
997
998 #[inline(always)]
999 fn fory_write_data_generic(
1000 &self,
1001 context: &mut WriteContext,
1002 has_generics: bool,
1003 ) -> Result<(), Error> {
1004 (**self).fory_write_data_generic(context, has_generics)
1005 }
1006
1007 #[inline(always)]
1008 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
1009 (**self).fory_type_id_dyn(type_resolver)
1010 }
1011
1012 #[inline(always)]
1013 fn as_any(&self) -> &dyn std::any::Any {
1014 (**self).as_any()
1015 }
1016
1017 #[inline(always)]
1018 fn fory_is_polymorphic() -> bool {
1019 true
1020 }
1021
1022 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
1023 Err(Error::not_allowed(
1024 "Box<dyn Serializer> is polymorphic - can's write type info statically",
1025 ))
1026 }
1027
1028 #[inline(always)]
1029 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
1030 context.read_any_type_info()?;
1031 Ok(())
1032 }
1033
1034 #[inline(always)]
1035 fn fory_read(
1036 context: &mut ReadContext,
1037 ref_mode: RefMode,
1038 read_type_info: bool,
1039 ) -> Result<Self, Error> {
1040 read_box_seralizer(context, ref_mode, read_type_info, None)
1041 }
1042
1043 #[inline(always)]
1044 fn fory_read_with_type_info(
1045 context: &mut ReadContext,
1046 ref_mode: RefMode,
1047 type_info: Rc<TypeInfo>,
1048 ) -> Result<Self, Error>
1049 where
1050 Self: Sized + ForyDefault,
1051 {
1052 read_box_seralizer(context, ref_mode, false, Some(type_info))
1053 }
1054
1055 fn fory_read_data(_context: &mut ReadContext) -> Result<Self, Error> {
1056 Err(Error::not_allowed(
1057 "fory_read_data should not be called directly on Box<dyn Serializer>",
1058 ))
1059 }
1060}
1061
1062fn read_box_seralizer(
1063 context: &mut ReadContext,
1064 ref_mode: RefMode,
1065 read_type_info: bool,
1066 type_info: Option<Rc<TypeInfo>>,
1067) -> Result<Box<dyn Serializer>, Error> {
1068 context.inc_depth()?;
1069 let ref_flag = if ref_mode != RefMode::None {
1070 context.reader.read_i8()?
1071 } else {
1072 RefFlag::NotNullValue as i8
1073 };
1074 if ref_flag != RefFlag::NotNullValue as i8 {
1075 return Err(Error::invalid_data(
1076 "Expected NotNullValue for Box<dyn Serializer>",
1077 ));
1078 }
1079 let typeinfo = if let Some(type_info) = type_info {
1080 type_info
1081 } else {
1082 ensure!(
1083 read_type_info,
1084 Error::invalid_data("Type info must be read for Box<dyn Serializer>")
1085 );
1086 context.read_any_type_info()?
1087 };
1088 let harness = typeinfo.get_harness();
1089 let boxed_any = harness.get_read_data_fn()(context)?;
1090 let trait_object = harness.get_to_serializer()(boxed_any)?;
1091 context.dec_depth();
1092 Ok(trait_object)
1093}