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