Skip to main content

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