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::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/// Helper macro for common type resolution and downcasting pattern
30#[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/// Helper macro for common type resolution and deserialization pattern
46#[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 to register trait object conversions for custom traits.
64///
65/// This macro automatically generates serializers for `Box<dyn Trait>` trait objects.
66/// Due to Rust's orphan rules, only `Box<dyn Trait>` is supported for user-defined traits.
67/// For `Rc<dyn Trait>` and `Arc<dyn Trait>`, wrapper types are generated (e.g., `TraitRc`, `TraitArc`),
68/// either you use the wrapper types or use the `Rc<dyn Any>` or `Arc<dyn Any>` instead if it's not
69/// inside struct fields. For struct fields, you can use the `Rc<dyn Trait>`, `Arc<dyn Trait>` directly,
70/// fory will generate converters for `Rc<dyn Trait>` and `Arc<dyn Trait>` to convert to wrapper for
71///
72/// The macro generates:
73/// - `Serializer` implementation for `Box<dyn Trait>`
74/// - `Default` implementation for `Box<dyn Trait>` (uses first registered type)
75///
76/// **Note**: Your trait must extend the `Serializer` trait.
77/// The `as_any()` method is automatically provided by the `Serializer` trait.
78///
79/// # Example
80///
81/// ```rust,ignore
82/// use fory_core::{fory::Fory, register_trait_type, serializer::Serializer};
83/// use fory_derive::ForyObject;
84///
85/// trait Animal: Serializer {
86///     fn speak(&self) -> String;
87///     fn name(&self) -> &str;
88/// }
89///
90/// #[derive(ForyObject, Debug)]
91/// struct Dog { name: String }
92///
93/// #[derive(ForyObject, Debug)]
94/// struct Cat { name: String }
95///
96/// impl Animal for Dog {
97///     fn speak(&self) -> String { "Woof!".to_string() }
98///     fn name(&self) -> &str { &self.name }
99/// }
100///
101/// impl Animal for Cat {
102///     fn speak(&self) -> String { "Meow!".to_string() }
103///     fn name(&self) -> &str { &self.name }
104/// }
105///
106/// register_trait_type!(Animal, Dog, Cat);
107///
108/// # fn main() {
109/// let mut fory = Fory::default().compatible(true);
110/// fory.register::<Dog>(100);
111/// fory.register::<Cat>(101);
112///
113/// let dog: Box<dyn Animal> = Box::new(Dog { name: "Rex".to_string() });
114/// let bytes = fory.serialize(&dog);
115/// let decoded: Box<dyn Animal> = fory.deserialize(&bytes).unwrap();
116/// assert_eq!(decoded.name(), "Rex");
117/// # }
118/// ```
119#[macro_export]
120macro_rules! register_trait_type {
121    ($trait_name:ident, $($impl_type:ty),+ $(,)?) => {
122        // 1. Generate Box<dyn Trait> serializer (existing functionality)
123        // ForyDefault implementation using first registered type
124        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        // 2. Auto-generate Rc wrapper type and conversions
131        $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        // 3. Auto-generate Arc wrapper type and conversions
143        $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        // 4. Serializer implementation for Box<dyn Trait> (existing functionality)
155        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                // This should not be called for polymorphic types like Box<dyn Trait>
235                // The fory_read method handles the polymorphic dispatch
236                $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    // Helper to get first type for Default impl
266    (@first_type $first_type:ty $(, $rest:ty)*) => {
267        $first_type
268    };
269}
270
271/// Unified macro to generate smart pointer wrapper types for traits
272/// Supports both Rc and Arc pointer types
273#[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 to read smart pointer trait objects (`Rc<dyn Trait>,` `Arc<dyn Trait>`)
358/// This macro handles ref tracking and directly constructs the trait object from concrete types
359#[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/// Shared serializer implementation for smart pointer wrappers
428#[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/// Helper macros for automatic conversions in derive code
539/// These are used by fory-derive to generate transparent conversions
540///
541/// Convert field of type `Rc<dyn Trait>` to wrapper for serialization
542#[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/// Convert wrapper back to `Rc<dyn Trait>` for deserialization
552#[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/// Convert `Arc<dyn Trait>` to wrapper for serialization
560#[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/// Convert `Vec<Rc<dyn Trait>>` to `Vec<wrapper>` for serialization
570#[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}