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