Skip to main content

fory_core/serializer/
trait_object.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18// Re-exports for use in macros - these are needed for macro expansion in user crates
19// Even though they appear unused in this file, they are used by the macro-generated code
20
21use 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/// Helper macro for common type resolution and downcasting pattern
32#[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 to register trait object conversions for custom traits.
48///
49/// This macro automatically generates serializers for `Box<dyn Trait>` trait objects.
50/// Due to Rust's orphan rules, only `Box<dyn Trait>` is supported for user-defined traits.
51/// For `Rc<dyn Trait>` and `Arc<dyn Trait>`, wrapper types are generated (e.g., `TraitRc`, `TraitArc`),
52/// either you use the wrapper types or use the `Rc<dyn Any>` or `Arc<dyn Any>` instead if it's not
53/// inside struct fields. For struct fields, you can use the `Rc<dyn Trait>`, `Arc<dyn Trait>` directly,
54/// fory will generate converters for `Rc<dyn Trait>` and `Arc<dyn Trait>` to convert to wrapper for
55///
56/// The macro generates:
57/// - `Serializer` implementation for `Box<dyn Trait>`
58/// - `Default` implementation for `Box<dyn Trait>` (uses first registered type)
59///
60/// **Note**: Your trait must extend the `Serializer` trait.
61/// The `as_any()` method is automatically provided by the `Serializer` trait.
62///
63/// # Example
64///
65/// ```rust,ignore
66/// use fory_core::{fory::Fory, register_trait_type, serializer::Serializer};
67/// use fory_derive::{ForyEnum, ForyStruct, ForyUnion};
68///
69/// trait Animal: Serializer {
70///     fn speak(&self) -> String;
71///     fn name(&self) -> &str;
72/// }
73///
74/// #[derive(ForyStruct, Debug)]
75/// struct Dog { name: String }
76///
77/// #[derive(ForyStruct, Debug)]
78/// struct Cat { name: String }
79///
80/// impl Animal for Dog {
81///     fn speak(&self) -> String { "Woof!".to_string() }
82///     fn name(&self) -> &str { &self.name }
83/// }
84///
85/// impl Animal for Cat {
86///     fn speak(&self) -> String { "Meow!".to_string() }
87///     fn name(&self) -> &str { &self.name }
88/// }
89///
90/// register_trait_type!(Animal, Dog, Cat);
91///
92/// # fn main() {
93/// let mut fory = Fory::builder().xlang(false).compatible(true).build();
94/// fory.register::<Dog>(100).unwrap();
95/// fory.register::<Cat>(101).unwrap();
96///
97/// let dog: Box<dyn Animal> = Box::new(Dog { name: "Rex".to_string() });
98/// let bytes = fory.serialize(&dog).unwrap();
99/// let decoded: Box<dyn Animal> = fory.deserialize(&bytes).unwrap();
100/// assert_eq!(decoded.name(), "Rex");
101/// # }
102/// ```
103#[macro_export]
104macro_rules! register_trait_type {
105    ($trait_name:ident, $($impl_type:ty),+ $(,)?) => {
106        // 1. Generate Box<dyn Trait> serializer (existing functionality)
107        // ForyDefault implementation using first registered type
108        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        // 2. Auto-generate Rc wrapper type and conversions
116        $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        // 3. Auto-generate Arc wrapper type and conversions
129        $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        // 4. Serializer implementation for Box<dyn Trait> (existing functionality)
142        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                // This should not be called for polymorphic types like Box<dyn Trait>
222                // The fory_read method handles the polymorphic dispatch
223                $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    // Helper to get first type for Default impl
253    (@first_type $first_type:ty $(, $rest:ty)*) => {
254        $first_type
255    };
256}
257
258/// Unified macro to generate smart pointer wrapper types for traits
259/// Supports both Rc and Arc pointer types
260#[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 to read smart pointer trait objects (`Rc<dyn Trait>,` `Arc<dyn Trait>`)
702/// This macro handles ref tracking and directly constructs the trait object from concrete types
703#[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/// Shared serializer implementation for smart pointer wrappers
806#[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/// Helper macros for automatic conversions in derive code
917/// These are used by fory-derive to generate transparent conversions
918///
919/// Convert field of type `Rc<dyn Trait>` to wrapper for serialization
920#[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/// Convert wrapper back to `Rc<dyn Trait>` for deserialization
930#[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/// Convert `Arc<dyn Trait>` to wrapper for serialization
938#[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/// Convert `Vec<Rc<dyn Trait>>` to `Vec<wrapper>` for serialization
948#[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}