fory_core/serializer/
any.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
18use crate::ensure;
19use crate::error::Error;
20use crate::resolver::context::{ReadContext, WriteContext};
21use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
22use crate::serializer::util::write_dyn_data_generic;
23use crate::serializer::{ForyDefault, Serializer};
24use crate::types::RefFlag;
25use crate::types::TypeId;
26use crate::types::{LIST, MAP, SET};
27use std::any::Any;
28use std::rc::Rc;
29use std::sync::Arc;
30
31/// Check if the type info represents a generic container type (LIST, SET, MAP).
32/// These types cannot be deserialized polymorphically via `Box<dyn Any>` because
33/// different generic instantiations (e.g., `Vec<A>`, `Vec<B>`) share the same type ID.
34#[inline]
35fn check_generic_container_type(type_info: &TypeInfo) -> Result<(), Error> {
36    let type_id = type_info.get_type_id();
37    if type_id == LIST || type_id == SET || type_id == MAP {
38        return Err(Error::type_error(
39            "Cannot deserialize generic container types (Vec, HashSet, HashMap) polymorphically \
40            via Box/Rc/Arc/Weak<dyn Any>. The serialization protocol does not preserve the element type \
41            information needed to distinguish between different generic instantiations \
42            (e.g., Vec<StructA> vs Vec<StructB>). Consider wrapping the container in a \
43            named struct type instead.",
44        ));
45    }
46    Ok(())
47}
48
49/// Helper function to deserialize to `Box<dyn Any>`
50pub fn deserialize_any_box(context: &mut ReadContext) -> Result<Box<dyn Any>, Error> {
51    context.inc_depth()?;
52    let ref_flag = context.reader.read_i8()?;
53    if ref_flag != RefFlag::NotNullValue as i8 {
54        return Err(Error::invalid_ref("Expected NotNullValue for Box<dyn Any>"));
55    }
56    let typeinfo = context.read_any_typeinfo()?;
57    // Check for generic container types which cannot be deserialized polymorphically
58    check_generic_container_type(&typeinfo)?;
59    let result = typeinfo
60        .get_harness()
61        .read_polymorphic_data(context, &typeinfo);
62    context.dec_depth();
63    result
64}
65
66impl ForyDefault for Box<dyn Any> {
67    fn fory_default() -> Self {
68        Box::new(())
69    }
70}
71
72impl Serializer for Box<dyn Any> {
73    fn fory_write(
74        &self,
75        context: &mut WriteContext,
76        write_ref_info: bool,
77        write_typeinfo: bool,
78        has_generics: bool,
79    ) -> Result<(), Error> {
80        write_box_any(
81            self.as_ref(),
82            context,
83            write_ref_info,
84            write_typeinfo,
85            has_generics,
86        )
87    }
88
89    fn fory_write_data_generic(
90        &self,
91        context: &mut WriteContext,
92        has_generics: bool,
93    ) -> Result<(), Error> {
94        let concrete_type_id = (**self).type_id();
95        let typeinfo = context.get_type_info(&concrete_type_id)?;
96        let serializer_fn = typeinfo.get_harness().get_write_data_fn();
97        serializer_fn(&**self, context, has_generics)
98    }
99
100    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
101        self.fory_write_data_generic(context, false)
102    }
103
104    fn fory_read(
105        context: &mut ReadContext,
106        read_ref_info: bool,
107        read_type_info: bool,
108    ) -> Result<Self, Error> {
109        read_box_any(context, read_ref_info, read_type_info, None)
110    }
111
112    fn fory_read_with_type_info(
113        context: &mut ReadContext,
114        read_ref_info: bool,
115        type_info: Rc<TypeInfo>,
116    ) -> Result<Self, Error>
117    where
118        Self: Sized + ForyDefault,
119    {
120        read_box_any(context, read_ref_info, false, Some(type_info))
121    }
122
123    fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
124        Err(Error::not_allowed(
125            "fory_read_data should not be called directly on polymorphic Rc<dyn Any> trait object",
126        ))
127    }
128
129    fn fory_get_type_id(_: &TypeResolver) -> Result<u32, Error> {
130        Err(Error::type_error(
131            "Box<dyn Any> has no static type ID - use fory_type_id_dyn",
132        ))
133    }
134
135    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
136        let concrete_type_id = (**self).type_id();
137        type_resolver
138            .get_fory_type_id(concrete_type_id)
139            .ok_or_else(|| Error::type_error("Type not registered"))
140    }
141
142    fn fory_concrete_type_id(&self) -> std::any::TypeId {
143        (**self).type_id()
144    }
145
146    fn fory_is_polymorphic() -> bool {
147        true
148    }
149
150    fn fory_is_shared_ref() -> bool {
151        false
152    }
153
154    fn fory_static_type_id() -> TypeId {
155        TypeId::UNKNOWN
156    }
157
158    fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
159        // Box<dyn Any> is polymorphic - type info is written per element
160        Ok(())
161    }
162
163    fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
164        // Box<dyn Any> is polymorphic - type info is read per element
165        Ok(())
166    }
167
168    fn as_any(&self) -> &dyn Any {
169        &**self
170    }
171}
172
173pub fn write_box_any(
174    value: &dyn Any,
175    context: &mut WriteContext,
176    write_ref_info: bool,
177    write_typeinfo: bool,
178    has_generics: bool,
179) -> Result<(), Error> {
180    if write_ref_info {
181        context.writer.write_i8(RefFlag::NotNullValue as i8);
182    }
183    let concrete_type_id = value.type_id();
184    let typeinfo = if write_typeinfo {
185        context.write_any_typeinfo(TypeId::UNKNOWN as u32, concrete_type_id)?
186    } else {
187        context.get_type_info(&concrete_type_id)?
188    };
189    let serializer_fn = typeinfo.get_harness().get_write_data_fn();
190    serializer_fn(value, context, has_generics)
191}
192
193pub fn read_box_any(
194    context: &mut ReadContext,
195    read_ref_info: bool,
196    read_type_info: bool,
197    type_info: Option<Rc<TypeInfo>>,
198) -> Result<Box<dyn Any>, Error> {
199    context.inc_depth()?;
200    let ref_flag = if read_ref_info {
201        context.reader.read_i8()?
202    } else {
203        RefFlag::NotNullValue as i8
204    };
205    if ref_flag != RefFlag::NotNullValue as i8 {
206        return Err(Error::invalid_data(
207            "Expected NotNullValue for Box<dyn Any>",
208        ));
209    }
210    let typeinfo = if let Some(type_info) = type_info {
211        type_info
212    } else {
213        ensure!(
214            read_type_info,
215            Error::invalid_data("Type info must be read for Box<dyn Any>")
216        );
217        context.read_any_typeinfo()?
218    };
219    // Check for generic container types which cannot be deserialized polymorphically
220    check_generic_container_type(&typeinfo)?;
221    let result = typeinfo
222        .get_harness()
223        .read_polymorphic_data(context, &typeinfo);
224    context.dec_depth();
225    result
226}
227
228impl ForyDefault for Rc<dyn Any> {
229    fn fory_default() -> Self {
230        Rc::new(())
231    }
232}
233
234impl Serializer for Rc<dyn Any> {
235    fn fory_write(
236        &self,
237        context: &mut WriteContext,
238        write_ref_info: bool,
239        write_type_info: bool,
240        has_generics: bool,
241    ) -> Result<(), Error> {
242        if !write_ref_info
243            || !context
244                .ref_writer
245                .try_write_rc_ref(&mut context.writer, self)
246        {
247            let concrete_type_id: std::any::TypeId = (**self).type_id();
248            let write_data_fn = if write_type_info {
249                let typeinfo =
250                    context.write_any_typeinfo(TypeId::UNKNOWN as u32, concrete_type_id)?;
251                typeinfo.get_harness().get_write_data_fn()
252            } else {
253                context
254                    .get_type_info(&concrete_type_id)?
255                    .get_harness()
256                    .get_write_data_fn()
257            };
258            write_data_fn(&**self, context, has_generics)?;
259        }
260        Ok(())
261    }
262
263    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
264        write_dyn_data_generic(self, context, false)
265    }
266
267    fn fory_write_data_generic(
268        &self,
269        context: &mut WriteContext,
270        has_generics: bool,
271    ) -> Result<(), Error> {
272        write_dyn_data_generic(self, context, has_generics)
273    }
274
275    fn fory_read(
276        context: &mut ReadContext,
277        read_ref_info: bool,
278        read_type_info: bool,
279    ) -> Result<Self, Error> {
280        read_rc_any(context, read_ref_info, read_type_info, None)
281    }
282
283    fn fory_read_with_type_info(
284        context: &mut ReadContext,
285        read_ref_info: bool,
286        type_info: Rc<TypeInfo>,
287    ) -> Result<Self, Error>
288    where
289        Self: Sized + ForyDefault,
290    {
291        read_rc_any(context, read_ref_info, false, Some(type_info))
292    }
293
294    fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
295        Err(Error::not_allowed(format!(
296            "fory_read_data should not be called directly on polymorphic Rc<dyn {}> trait object",
297            stringify!($trait_name)
298        )))
299    }
300
301    fn fory_get_type_id(_: &TypeResolver) -> Result<u32, Error> {
302        Err(Error::type_error(
303            "Rc<dyn Any> has no static type ID - use fory_type_id_dyn",
304        ))
305    }
306
307    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
308        let concrete_type_id = (**self).type_id();
309        type_resolver
310            .get_fory_type_id(concrete_type_id)
311            .ok_or_else(|| Error::type_error("Type not registered"))
312    }
313
314    fn fory_concrete_type_id(&self) -> std::any::TypeId {
315        (**self).type_id()
316    }
317
318    fn fory_is_shared_ref() -> bool {
319        true
320    }
321
322    fn fory_is_polymorphic() -> bool {
323        true
324    }
325
326    fn fory_static_type_id() -> TypeId {
327        TypeId::UNKNOWN
328    }
329
330    fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
331        // Rc<dyn Any> is polymorphic - type info is written per element
332        Ok(())
333    }
334
335    fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
336        // Rc<dyn Any> is polymorphic - type info is read per element
337        Ok(())
338    }
339
340    fn as_any(&self) -> &dyn Any {
341        &**self
342    }
343}
344
345pub fn read_rc_any(
346    context: &mut ReadContext,
347    read_ref_info: bool,
348    read_type_info: bool,
349    type_info: Option<Rc<TypeInfo>>,
350) -> Result<Rc<dyn Any>, Error> {
351    let ref_flag = if read_ref_info {
352        context.ref_reader.read_ref_flag(&mut context.reader)?
353    } else {
354        RefFlag::NotNullValue
355    };
356    match ref_flag {
357        RefFlag::Null => Err(Error::invalid_ref("Rc<dyn Any> cannot be null")),
358        RefFlag::Ref => {
359            let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
360            context
361                .ref_reader
362                .get_rc_ref::<dyn Any>(ref_id)
363                .ok_or_else(|| {
364                    Error::invalid_data(format!("Rc<dyn Any> reference {} not found", ref_id))
365                })
366        }
367        RefFlag::NotNullValue => {
368            context.inc_depth()?;
369            let typeinfo = if read_type_info {
370                context.read_any_typeinfo()?
371            } else {
372                type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
373            };
374            // Check for generic container types which cannot be deserialized polymorphically
375            check_generic_container_type(&typeinfo)?;
376            let boxed = typeinfo
377                .get_harness()
378                .read_polymorphic_data(context, &typeinfo)?;
379            context.dec_depth();
380            Ok(Rc::<dyn Any>::from(boxed))
381        }
382        RefFlag::RefValue => {
383            context.inc_depth()?;
384            let typeinfo = if read_type_info {
385                context.read_any_typeinfo()?
386            } else {
387                type_info.ok_or_else(|| Error::type_error("No type info found for read"))?
388            };
389            // Check for generic container types which cannot be deserialized polymorphically
390            check_generic_container_type(&typeinfo)?;
391            let boxed = typeinfo
392                .get_harness()
393                .read_polymorphic_data(context, &typeinfo)?;
394            context.dec_depth();
395            let rc: Rc<dyn Any> = Rc::from(boxed);
396            context.ref_reader.store_rc_ref(rc.clone());
397            Ok(rc)
398        }
399    }
400}
401
402impl ForyDefault for Arc<dyn Any> {
403    fn fory_default() -> Self {
404        Arc::new(())
405    }
406}
407
408impl Serializer for Arc<dyn Any> {
409    fn fory_write(
410        &self,
411        context: &mut WriteContext,
412        write_ref_info: bool,
413        write_type_info: bool,
414        has_generics: bool,
415    ) -> Result<(), Error> {
416        if !write_ref_info
417            || !context
418                .ref_writer
419                .try_write_arc_ref(&mut context.writer, self)
420        {
421            let concrete_type_id: std::any::TypeId = (**self).type_id();
422            if write_type_info {
423                let typeinfo =
424                    context.write_any_typeinfo(TypeId::UNKNOWN as u32, concrete_type_id)?;
425                let serializer_fn = typeinfo.get_harness().get_write_data_fn();
426                serializer_fn(&**self, context, has_generics)?;
427            } else {
428                let serializer_fn = context
429                    .get_type_info(&concrete_type_id)?
430                    .get_harness()
431                    .get_write_data_fn();
432                serializer_fn(&**self, context, has_generics)?;
433            }
434        }
435        Ok(())
436    }
437
438    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
439        write_dyn_data_generic(self, context, false)
440    }
441
442    fn fory_write_data_generic(
443        &self,
444        context: &mut WriteContext,
445        has_generics: bool,
446    ) -> Result<(), Error> {
447        write_dyn_data_generic(self, context, has_generics)
448    }
449
450    fn fory_read(
451        context: &mut ReadContext,
452        read_ref_info: bool,
453        read_type_info: bool,
454    ) -> Result<Self, Error> {
455        read_arc_any(context, read_ref_info, read_type_info, None)
456    }
457
458    fn fory_read_with_type_info(
459        context: &mut ReadContext,
460        read_ref_info: bool,
461        type_info: Rc<TypeInfo>,
462    ) -> Result<Self, Error>
463    where
464        Self: Sized + ForyDefault,
465    {
466        read_arc_any(context, read_ref_info, false, Some(type_info))
467    }
468
469    fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
470        Err(Error::not_allowed(format!(
471            "fory_read_data should not be called directly on polymorphic Rc<dyn {}> trait object",
472            stringify!($trait_name)
473        )))
474    }
475
476    fn fory_get_type_id(_type_resolver: &TypeResolver) -> Result<u32, Error> {
477        Err(Error::type_error(
478            "Arc<dyn Any> has no static type ID - use fory_type_id_dyn",
479        ))
480    }
481
482    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
483        let concrete_type_id = (**self).type_id();
484        type_resolver
485            .get_fory_type_id(concrete_type_id)
486            .ok_or_else(|| Error::type_error("Type not registered"))
487    }
488
489    fn fory_concrete_type_id(&self) -> std::any::TypeId {
490        (**self).type_id()
491    }
492
493    fn fory_is_polymorphic() -> bool {
494        true
495    }
496
497    fn fory_is_shared_ref() -> bool {
498        true
499    }
500
501    fn fory_static_type_id() -> TypeId {
502        TypeId::UNKNOWN
503    }
504
505    fn fory_write_type_info(_context: &mut WriteContext) -> Result<(), Error> {
506        // Arc<dyn Any> is polymorphic - type info is written per element
507        Ok(())
508    }
509
510    fn fory_read_type_info(_context: &mut ReadContext) -> Result<(), Error> {
511        // Arc<dyn Any> is polymorphic - type info is read per element
512        Ok(())
513    }
514
515    fn as_any(&self) -> &dyn Any {
516        &**self
517    }
518}
519
520pub fn read_arc_any(
521    context: &mut ReadContext,
522    read_ref_info: bool,
523    read_type_info: bool,
524    type_info: Option<Rc<TypeInfo>>,
525) -> Result<Arc<dyn Any>, Error> {
526    let ref_flag = if read_ref_info {
527        context.ref_reader.read_ref_flag(&mut context.reader)?
528    } else {
529        RefFlag::NotNullValue
530    };
531    match ref_flag {
532        RefFlag::Null => Err(Error::invalid_ref("Arc<dyn Any> cannot be null")),
533        RefFlag::Ref => {
534            let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
535            context
536                .ref_reader
537                .get_arc_ref::<dyn Any>(ref_id)
538                .ok_or_else(|| {
539                    Error::invalid_data(format!("Arc<dyn Any> reference {} not found", ref_id))
540                })
541        }
542        RefFlag::NotNullValue => {
543            context.inc_depth()?;
544            let typeinfo = if read_type_info {
545                context.read_any_typeinfo()?
546            } else {
547                type_info
548                    .ok_or_else(|| Error::type_error("No type info found for read Arc<dyn Any>"))?
549            };
550            // Check for generic container types which cannot be deserialized polymorphically
551            check_generic_container_type(&typeinfo)?;
552            let boxed = typeinfo
553                .get_harness()
554                .read_polymorphic_data(context, &typeinfo)?;
555            context.dec_depth();
556            Ok(Arc::<dyn Any>::from(boxed))
557        }
558        RefFlag::RefValue => {
559            context.inc_depth()?;
560            let typeinfo = if read_type_info {
561                context.read_any_typeinfo()?
562            } else {
563                type_info
564                    .ok_or_else(|| Error::type_error("No type info found for read Arc<dyn Any>"))?
565            };
566            // Check for generic container types which cannot be deserialized polymorphically
567            check_generic_container_type(&typeinfo)?;
568            let boxed = typeinfo
569                .get_harness()
570                .read_polymorphic_data(context, &typeinfo)?;
571            context.dec_depth();
572            let arc: Arc<dyn Any> = Arc::from(boxed);
573            context.ref_reader.store_arc_ref(arc.clone());
574            Ok(arc)
575        }
576    }
577}