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