1use crate::ensure;
22use crate::error::Error;
23use crate::resolver::context::{ReadContext, WriteContext};
24use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
25use crate::serializer::{ForyDefault, Serializer};
26use crate::RefFlag;
27use std::rc::Rc;
28
29#[macro_export]
31macro_rules! downcast_and_serialize {
32 ($any_ref:expr, $context:expr, $trait_name:ident, $($impl_type:ty),+) => {{
33 $(
34 if $any_ref.type_id() == std::any::TypeId::of::<$impl_type>() {
35 if let Some(concrete) = $any_ref.downcast_ref::<$impl_type>() {
36 concrete.fory_write_data($context)?;
37 return Ok(());
38 }
39 }
40 )*
41 return Err(fory_core::Error::type_error(format!("Failed to downcast to any registered type for trait {}", stringify!($trait_name))));
42 }};
43}
44
45#[macro_export]
47macro_rules! resolve_and_deserialize {
48 ($fory_type_id:expr, $context:expr, $constructor:expr, $trait_name:ident, $($impl_type:ty),+) => {{
49 $(
50 if let Some(registered_type_id) = $context.get_type_resolver().get_fory_type_id(std::any::TypeId::of::<$impl_type>()) {
51 if $fory_type_id == registered_type_id {
52 let concrete_obj = <$impl_type as fory_core::Serializer>::fory_read_data($context)?;
53 return Ok($constructor(concrete_obj));
54 }
55 }
56 )*
57 Err(fory_core::Error::type_error(
58 format!("Type ID {} not registered for trait {}", $fory_type_id, stringify!($trait_name))
59 ))
60 }};
61}
62
63#[macro_export]
120macro_rules! register_trait_type {
121 ($trait_name:ident, $($impl_type:ty),+ $(,)?) => {
122 impl $crate::serializer::ForyDefault for Box<dyn $trait_name> {
125 fn fory_default() -> Self {
126 Box::new(<register_trait_type!(@first_type $($impl_type),+) as $crate::serializer::ForyDefault>::fory_default())
127 }
128 }
129
130 $crate::generate_smart_pointer_wrapper!(
132 std::rc::Rc,
133 Rc,
134 std::rc::Rc::get_mut,
135 $trait_name,
136 try_write_rc_ref,
137 get_rc_ref,
138 store_rc_ref,
139 $($impl_type),+
140 );
141
142 $crate::generate_smart_pointer_wrapper!(
144 std::sync::Arc,
145 Arc,
146 std::sync::Arc::get_mut,
147 $trait_name,
148 try_write_arc_ref,
149 get_arc_ref,
150 store_arc_ref,
151 $($impl_type),+
152 );
153
154 impl fory_core::Serializer for Box<dyn $trait_name> {
156 #[inline(always)]
157 fn fory_write(&self, context: &mut fory_core::WriteContext, write_ref_info: bool, write_type_info: bool, has_generics: bool) -> Result<(), fory_core::Error> {
158 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
159 fory_core::serializer::write_box_any(any_ref, context, write_ref_info, write_type_info, has_generics)
160 }
161
162 #[inline(always)]
163 fn fory_write_data(&self, context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
164 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
165 fory_core::serializer::write_box_any(any_ref, context, false, false, false)
166 }
167
168 #[inline(always)]
169 fn fory_write_data_generic(&self, context: &mut fory_core::WriteContext, has_generics: bool) -> Result<(), fory_core::Error> {
170 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
171 fory_core::serializer::write_box_any(any_ref, context, false, false, has_generics)
172 }
173
174 #[inline(always)]
175 fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, fory_core::Error> {
176 let any_ref = <dyn $trait_name as fory_core::Serializer>::as_any(&**self);
177 let concrete_type_id = any_ref.type_id();
178 type_resolver
179 .get_fory_type_id(concrete_type_id)
180 .ok_or_else(|| fory_core::Error::type_error("Type not registered for trait object"))
181 }
182
183 #[inline(always)]
184 fn fory_is_polymorphic() -> bool {
185 true
186 }
187
188 fn fory_write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
189 $crate::not_allowed!("fory_write_type_info should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
190 }
191
192 fn fory_read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
193 $crate::not_allowed!("fory_read_type_info should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
194 }
195
196 fn fory_read(context: &mut fory_core::ReadContext, read_ref_info: bool, read_type_info: bool) -> Result<Self, fory_core::Error> {
197 let boxed_any = fory_core::serializer::read_box_any(context, read_ref_info, read_type_info, None)?;
198 $(
199 if boxed_any.is::<$impl_type>() {
200 let concrete = boxed_any.downcast::<$impl_type>()
201 .map_err(|_| fory_core::Error::type_error("Downcast failed"))?;
202 let ptr = Box::new(*concrete);
203 return Ok(Self::from(ptr));
204 }
205 )*
206 Err(fory_core::Error::type_error(
207 format!("Deserialized type does not implement trait {}", stringify!($trait_name))
208 ))
209 }
210
211 fn fory_read_with_type_info(
212 context: &mut fory_core::ReadContext,
213 read_ref_info: bool,
214 type_info: std::rc::Rc<fory_core::TypeInfo>,
215 ) -> Result<Self, fory_core::Error>
216 where
217 Self: Sized + fory_core::ForyDefault,
218 {
219 let boxed_any = fory_core::serializer::read_box_any(context, read_ref_info, false, Some(type_info))?;
220 $(
221 if boxed_any.is::<$impl_type>() {
222 let concrete = boxed_any.downcast::<$impl_type>()
223 .map_err(|_| fory_core::Error::type_error("Downcast failed"))?;
224 let ptr = Box::new(*concrete);
225 return Ok(Self::from(ptr));
226 }
227 )*
228 Err(fory_core::Error::type_error(
229 format!("Deserialized type does not implement trait {}", stringify!($trait_name))
230 ))
231 }
232
233 fn fory_read_data(_context: &mut fory_core::ReadContext) -> Result<Self, fory_core::Error> {
234 $crate::not_allowed!("fory_read_data should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
237 }
238
239 fn fory_get_type_id(_type_resolver: &fory_core::TypeResolver) -> Result<u32, fory_core::Error> {
240 $crate::not_allowed!("fory_get_type_id should not be called directly on polymorphic Box<dyn {}> trait object", stringify!($trait_name))
241 }
242
243 #[inline(always)]
244 fn fory_static_type_id() -> fory_core::TypeId {
245 fory_core::TypeId::UNKNOWN
246 }
247
248 #[inline(always)]
249 fn fory_reserved_space() -> usize {
250 $crate::types::SIZE_OF_REF_AND_TYPE
251 }
252
253 #[inline(always)]
254 fn fory_concrete_type_id(&self) -> std::any::TypeId {
255 <dyn $trait_name as fory_core::Serializer>::as_any(&**self).type_id()
256 }
257
258 #[inline(always)]
259 fn as_any(&self) -> &dyn std::any::Any {
260 <dyn $trait_name as fory_core::Serializer>::as_any(&**self)
261 }
262 }
263 };
264
265 (@first_type $first_type:ty $(, $rest:ty)*) => {
267 $first_type
268 };
269}
270
271#[macro_export]
274macro_rules! generate_smart_pointer_wrapper {
275 ($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),+ $(,)?) => {
276 $crate::paste::paste! {
277 #[derive(Clone)]
278 pub(crate) struct [<$trait_name $ptr_name>]($ptr_path<dyn $trait_name>);
279
280 impl [<$trait_name $ptr_name>] {
281 pub(crate) fn new(inner: $ptr_path<dyn $trait_name>) -> Self {
282 Self(inner)
283 }
284
285 pub(crate) fn into_inner(self) -> $ptr_path<dyn $trait_name> {
286 self.0
287 }
288
289 pub(crate) fn unwrap(self) -> $ptr_path<dyn $trait_name> {
290 self.0
291 }
292
293 pub(crate) fn as_ref(&self) -> &dyn $trait_name {
294 &*self.0
295 }
296 }
297
298 impl std::ops::Deref for [<$trait_name $ptr_name>] {
299 type Target = dyn $trait_name;
300
301 fn deref(&self) -> &Self::Target {
302 &*self.0
303 }
304 }
305
306 impl std::ops::DerefMut for [<$trait_name $ptr_name>] {
307 fn deref_mut(&mut self) -> &mut Self::Target {
308 $get_mut(&mut self.0)
309 .expect(&format!("Cannot get mutable reference to {} with multiple strong references", stringify!($ptr_name)))
310 }
311 }
312
313 impl From<$ptr_path<dyn $trait_name>> for [<$trait_name $ptr_name>] {
314 fn from(ptr: $ptr_path<dyn $trait_name>) -> Self {
315 Self::new(ptr)
316 }
317 }
318
319 impl From<[<$trait_name $ptr_name>]> for $ptr_path<dyn $trait_name> {
320 fn from(wrapper: [<$trait_name $ptr_name>]) -> Self {
321 wrapper.into_inner()
322 }
323 }
324
325 impl $crate::serializer::ForyDefault for [<$trait_name $ptr_name>] {
326 fn fory_default() -> Self {
327 Self($ptr_path::new(<$crate::register_trait_type!(@first_type $($impl_type),+) as $crate::serializer::ForyDefault>::fory_default()))
328 }
329 }
330
331 impl std::fmt::Debug for [<$trait_name $ptr_name>] {
332 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
333 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
334 $(
335 if let Some(concrete) = any_obj.downcast_ref::<$impl_type>() {
336 return write!(f, concat!(stringify!($trait_name), stringify!($ptr_name), "({:?})"), concrete);
337 }
338 )*
339 write!(f, concat!(stringify!($trait_name), stringify!($ptr_name), "({:p})"), &*self.0)
340 }
341 }
342
343 $crate::impl_smart_pointer_serializer!(
344 [<$trait_name $ptr_name>],
345 $ptr_path<dyn $trait_name>,
346 $ptr_path::new,
347 $trait_name,
348 $try_write_ref,
349 $get_ref,
350 $store_ref,
351 $($impl_type),+
352 );
353 }
354 };
355}
356
357#[macro_export]
360macro_rules! read_ptr_trait_object {
361 ($context:expr, $read_ref_info: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),+) => {{
362 let ref_flag = if $read_ref_info {
363 $context.ref_reader.read_ref_flag(&mut $context.reader)?
364 } else {
365 fory_core::RefFlag::NotNullValue
366 };
367 match ref_flag {
368 fory_core::RefFlag::Null => Err(fory_core::Error::invalid_ref(format!("smart pointer to dyn {} cannot be null", stringify!($trait_name)))),
369 fory_core::RefFlag::Ref => {
370 let ref_id = $context.ref_reader.read_ref_id(&mut $context.reader)?;
371 let ptr_ref = $context.ref_reader.$get_ref::<dyn $trait_name>(ref_id)
372 .ok_or_else(|| fory_core::Error::invalid_data(format!("dyn {} reference {} not found", stringify!($trait_name), ref_id)))?;
373 Ok(Self::from(ptr_ref))
374 }
375 fory_core::RefFlag::NotNullValue => {
376 $context.inc_depth()?;
377 let typeinfo = if $read_type_info {
378 $context.read_any_typeinfo()?
379 } else {
380 $type_info.ok_or_else(|| fory_core::Error::type_error("No type info found for read"))?
381 };
382 let fory_type_id = typeinfo.get_type_id();
383 $(
384 if let Some(registered_type_id) = $context.get_type_resolver().get_fory_type_id(std::any::TypeId::of::<$impl_type>()) {
385 if fory_type_id == registered_type_id {
386 let concrete_obj = <$impl_type as fory_core::Serializer>::fory_read_data($context)?;
387 $context.dec_depth();
388 let ptr = $constructor_expr(concrete_obj) as $pointer_type;
389 return Ok(Self::from(ptr));
390 }
391 }
392 )*
393 $context.dec_depth();
394 Err(fory_core::Error::type_error(
395 format!("Type ID {} not registered for trait {}", fory_type_id, stringify!($trait_name))
396 ))
397 }
398 fory_core::RefFlag::RefValue => {
399 $context.inc_depth()?;
400 let typeinfo = if $read_type_info {
401 $context.read_any_typeinfo()?
402 } else {
403 $type_info.ok_or_else(|| fory_core::Error::type_error("No type info found for read"))?
404 };
405 let fory_type_id = typeinfo.get_type_id();
406 $(
407 if let Some(registered_type_id) = $context.get_type_resolver().get_fory_type_id(std::any::TypeId::of::<$impl_type>()) {
408 if fory_type_id == registered_type_id {
409 let concrete_obj = <$impl_type as fory_core::Serializer>::fory_read_data($context)?;
410 $context.dec_depth();
411 let ptr = $constructor_expr(concrete_obj) as $pointer_type;
412 let wrapper = Self::from(ptr.clone());
413 $context.ref_reader.$store_ref(ptr);
414 return Ok(wrapper);
415 }
416 }
417 )*
418 $context.dec_depth();
419 Err(fory_core::Error::type_error(
420 format!("Type ID {} not registered for trait {}", fory_type_id, stringify!($trait_name))
421 ))
422 }
423 }
424 }};
425}
426
427#[macro_export]
429macro_rules! impl_smart_pointer_serializer {
430 ($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),+) => {
431 impl fory_core::Serializer for $wrapper_name {
432 fn fory_write(&self, context: &mut fory_core::WriteContext, write_ref_info: bool, write_type_info: bool, has_generics: bool) -> Result<(), fory_core::Error> {
433 if !write_ref_info || !context.ref_writer.$try_write_ref(&mut context.writer, &self.0) {
434 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
435 let concrete_type_id = any_obj.type_id();
436 let typeinfo = if write_type_info {
437 context.write_any_typeinfo(fory_core::TypeId::UNKNOWN as u32, concrete_type_id)?
438 } else {
439 context.get_type_info(&concrete_type_id)?
440 };
441 let serializer_fn = typeinfo.get_harness().get_write_data_fn();
442 serializer_fn(any_obj, context, has_generics)?;
443 }
444 Ok(())
445 }
446
447 fn fory_write_data(&self, context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
448 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
449 $crate::downcast_and_serialize!(any_obj, context, $trait_name, $($impl_type),+)
450 }
451
452 fn fory_read(context: &mut fory_core::ReadContext, read_ref_info: bool, read_type_info: bool) -> Result<Self, fory_core::Error> {
453 $crate::read_ptr_trait_object!(
454 context,
455 read_ref_info,
456 read_type_info,
457 None,
458 $pointer_type,
459 $trait_name,
460 $constructor_expr,
461 $get_ref,
462 $store_ref,
463 $($impl_type),+
464 )
465 }
466
467 fn fory_read_with_type_info(context: &mut fory_core::ReadContext, read_ref_info: bool, type_info: std::rc::Rc<fory_core::TypeInfo>) -> Result<Self, fory_core::Error> {
468 $crate::read_ptr_trait_object!(
469 context,
470 read_ref_info,
471 false,
472 Some(type_info),
473 $pointer_type,
474 $trait_name,
475 $constructor_expr,
476 $get_ref,
477 $store_ref,
478 $($impl_type),+
479 )
480 }
481
482 fn fory_read_data(context: &mut fory_core::ReadContext) -> Result<Self, fory_core::Error> {
483 $crate::not_allowed!("fory_read_data should not be called directly on polymorphic {}<dyn {}> trait object", stringify!($ptr_path), stringify!($trait_name))
484 }
485
486 #[inline(always)]
487 fn fory_get_type_id(_type_resolver: &fory_core::TypeResolver) -> Result<u32, fory_core::Error> {
488 Ok(fory_core::TypeId::STRUCT as u32)
489 }
490
491 #[inline(always)]
492 fn fory_static_type_id() -> fory_core::TypeId {
493 fory_core::TypeId::UNKNOWN
494 }
495
496 #[inline(always)]
497 fn fory_write_type_info(_context: &mut fory_core::WriteContext) -> Result<(), fory_core::Error> {
498 Ok(())
499 }
500
501 #[inline(always)]
502 fn fory_read_type_info(_context: &mut fory_core::ReadContext) -> Result<(), fory_core::Error> {
503 Ok(())
504 }
505
506 #[inline(always)]
507 fn fory_is_polymorphic() -> bool {
508 true
509 }
510
511 #[inline(always)]
512 fn fory_is_shared_ref() -> bool {
513 true
514 }
515
516 #[inline(always)]
517 fn fory_type_id_dyn(&self, type_resolver: &fory_core::TypeResolver) -> Result<u32, fory_core::Error> {
518 let any_obj = <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0);
519 let concrete_type_id = any_obj.type_id();
520 type_resolver
521 .get_fory_type_id(concrete_type_id)
522 .ok_or_else(|| fory_core::Error::type_error("Type not registered for trait object"))
523 }
524
525 #[inline(always)]
526 fn fory_concrete_type_id(&self) -> std::any::TypeId {
527 <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0).type_id()
528 }
529
530 #[inline(always)]
531 fn as_any(&self) -> &dyn std::any::Any {
532 <dyn $trait_name as fory_core::Serializer>::as_any(&*self.0)
533 }
534 }
535 };
536}
537
538#[macro_export]
543macro_rules! wrap_rc {
544 ($field:expr, $trait_name:ident) => {
545 $crate::paste::paste! {
546 [<$trait_name Rc>]::from($field)
547 }
548 };
549}
550
551#[macro_export]
553macro_rules! unwrap_rc {
554 ($wrapper:expr, $trait_name:ident) => {
555 std::rc::Rc::<dyn $trait_name>::from($wrapper)
556 };
557}
558
559#[macro_export]
561macro_rules! wrap_arc {
562 ($field:expr, $trait_name:ident) => {
563 $crate::paste::paste! {
564 [<$trait_name Arc>]::from($field)
565 }
566 };
567}
568
569#[macro_export]
571macro_rules! wrap_vec_rc {
572 ($vec:expr, $trait_name:ident) => {
573 $crate::paste::paste! {
574 $vec.into_iter().map(|item| [<$trait_name Rc>]::from(item)).collect()
575 }
576 };
577}
578
579impl Default for Box<dyn Serializer> {
580 fn default() -> Self {
581 Box::new(0)
582 }
583}
584
585impl ForyDefault for Box<dyn Serializer> {
586 fn fory_default() -> Self {
587 Box::new(0)
588 }
589}
590
591impl Serializer for Box<dyn Serializer> {
592 #[inline(always)]
593 fn fory_concrete_type_id(&self) -> std::any::TypeId {
594 (**self).fory_concrete_type_id()
595 }
596
597 fn fory_write(
598 &self,
599 context: &mut WriteContext,
600 write_ref_info: bool,
601 write_type_info: bool,
602 has_generics: bool,
603 ) -> Result<(), Error> {
604 if write_ref_info {
605 context.writer.write_i8(RefFlag::NotNullValue as i8);
606 }
607 let fory_type_id_dyn = self.fory_type_id_dyn(context.get_type_resolver())?;
608 let concrete_type_id = (**self).fory_concrete_type_id();
609 if write_type_info {
610 context.write_any_typeinfo(fory_type_id_dyn, concrete_type_id)?;
611 };
612 self.fory_write_data_generic(context, has_generics)
613 }
614
615 #[inline(always)]
616 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
617 self.fory_write_data_generic(context, false)
618 }
619
620 #[inline(always)]
621 fn fory_write_data_generic(
622 &self,
623 context: &mut WriteContext,
624 has_generics: bool,
625 ) -> Result<(), Error> {
626 (**self).fory_write_data_generic(context, has_generics)
627 }
628
629 #[inline(always)]
630 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
631 (**self).fory_type_id_dyn(type_resolver)
632 }
633
634 #[inline(always)]
635 fn as_any(&self) -> &dyn std::any::Any {
636 (**self).as_any()
637 }
638
639 #[inline(always)]
640 fn fory_is_polymorphic() -> bool {
641 true
642 }
643
644 fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
645 Err(Error::not_allowed(
646 "Box<dyn Serializer> is polymorphic - can's write type info statically",
647 ))
648 }
649
650 #[inline(always)]
651 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
652 context.read_any_typeinfo()?;
653 Ok(())
654 }
655
656 #[inline(always)]
657 fn fory_read(
658 context: &mut ReadContext,
659 read_ref_info: bool,
660 read_type_info: bool,
661 ) -> Result<Self, Error> {
662 read_box_seralizer(context, read_ref_info, read_type_info, None)
663 }
664
665 #[inline(always)]
666 fn fory_read_with_type_info(
667 context: &mut ReadContext,
668 read_ref_info: bool,
669 type_info: Rc<TypeInfo>,
670 ) -> Result<Self, Error>
671 where
672 Self: Sized + ForyDefault,
673 {
674 read_box_seralizer(context, read_ref_info, false, Some(type_info))
675 }
676
677 fn fory_read_data(_context: &mut ReadContext) -> Result<Self, Error> {
678 Err(Error::not_allowed(
679 "fory_read_data should not be called directly on Box<dyn Serializer>",
680 ))
681 }
682}
683
684fn read_box_seralizer(
685 context: &mut ReadContext,
686 read_ref_info: bool,
687 read_type_info: bool,
688 type_info: Option<Rc<TypeInfo>>,
689) -> Result<Box<dyn Serializer>, Error> {
690 context.inc_depth()?;
691 let ref_flag = if read_ref_info {
692 context.reader.read_i8()?
693 } else {
694 RefFlag::NotNullValue as i8
695 };
696 if ref_flag != RefFlag::NotNullValue as i8 {
697 return Err(Error::invalid_data(
698 "Expected NotNullValue for Box<dyn Serializer>",
699 ));
700 }
701 let typeinfo = if let Some(type_info) = type_info {
702 type_info
703 } else {
704 ensure!(
705 read_type_info,
706 Error::invalid_data("Type info must be read for Box<dyn Serializer>")
707 );
708 context.read_any_typeinfo()?
709 };
710 let harness = typeinfo.get_harness();
711 let boxed_any = harness.get_read_data_fn()(context)?;
712 let trait_object = harness.get_to_serializer()(boxed_any)?;
713 context.dec_depth();
714 Ok(trait_object)
715}