fory_core/serializer/
arc.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::error::Error;
19use crate::resolver::context::{ReadContext, WriteContext};
20use crate::resolver::type_resolver::{TypeInfo, TypeResolver};
21use crate::serializer::{ForyDefault, Serializer};
22use crate::types::RefFlag;
23use crate::types::TypeId;
24use std::rc::Rc;
25use std::sync::Arc;
26
27impl<T: Serializer + ForyDefault + Send + Sync + 'static> Serializer for Arc<T> {
28    fn fory_is_shared_ref() -> bool {
29        true
30    }
31
32    fn fory_write(
33        &self,
34        context: &mut WriteContext,
35        write_ref_info: bool,
36        write_type_info: bool,
37        has_generics: bool,
38    ) -> Result<(), Error> {
39        if !write_ref_info
40            || !context
41                .ref_writer
42                .try_write_arc_ref(&mut context.writer, self)
43        {
44            if T::fory_is_shared_ref() || T::fory_is_polymorphic() {
45                let inner_write_ref = T::fory_is_shared_ref();
46                return T::fory_write(
47                    &**self,
48                    context,
49                    inner_write_ref,
50                    write_type_info,
51                    has_generics,
52                );
53            }
54            if write_type_info {
55                T::fory_write_type_info(context)?;
56            }
57            T::fory_write_data_generic(self, context, has_generics)
58        } else {
59            Ok(())
60        }
61    }
62
63    fn fory_write_data_generic(&self, _: &mut WriteContext, _: bool) -> Result<(), Error> {
64        Err(Error::not_allowed(
65            "Arc<T> should be written using `fory_write` to handle reference tracking properly",
66        ))
67    }
68
69    fn fory_write_data(&self, _: &mut WriteContext) -> Result<(), Error> {
70        Err(Error::not_allowed(
71            "Arc<T> should be written using `fory_write` to handle reference tracking properly",
72        ))
73    }
74
75    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
76        T::fory_write_type_info(context)
77    }
78
79    fn fory_read(
80        context: &mut ReadContext,
81        read_ref_info: bool,
82        read_type_info: bool,
83    ) -> Result<Self, Error> {
84        // if read_ref_info is false, shared refs will be deserialized into new objects each time.
85        read_arc(context, read_ref_info, read_type_info, None)
86    }
87
88    fn fory_read_with_type_info(
89        context: &mut ReadContext,
90        read_ref_info: bool,
91        typeinfo: Rc<TypeInfo>,
92    ) -> Result<Self, Error>
93    where
94        Self: Sized + ForyDefault,
95    {
96        read_arc(context, read_ref_info, false, Some(typeinfo))
97    }
98
99    fn fory_read_data(_: &mut ReadContext) -> Result<Self, Error> {
100        Err(Error::not_allowed("Arc<T> should be read using `fory_read/fory_read_with_type_info` to handle reference tracking properly"))
101    }
102
103    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
104        T::fory_read_type_info(context)
105    }
106
107    fn fory_reserved_space() -> usize {
108        // Arc is a shared ref, so we just need space for the ref tracking
109        // We don't recursively compute inner type's space to avoid infinite recursion
110        4
111    }
112
113    fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<u32, Error> {
114        T::fory_get_type_id(type_resolver)
115    }
116
117    fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<u32, Error> {
118        (**self).fory_type_id_dyn(type_resolver)
119    }
120
121    fn fory_static_type_id() -> TypeId {
122        T::fory_static_type_id()
123    }
124
125    fn as_any(&self) -> &dyn std::any::Any {
126        self
127    }
128}
129
130fn read_arc<T: Serializer + ForyDefault + 'static>(
131    context: &mut ReadContext,
132    read_ref_info: bool,
133    read_type_info: bool,
134    typeinfo: Option<Rc<TypeInfo>>,
135) -> Result<Arc<T>, Error> {
136    let ref_flag = if read_ref_info {
137        context.ref_reader.read_ref_flag(&mut context.reader)?
138    } else {
139        RefFlag::NotNullValue
140    };
141    match ref_flag {
142        RefFlag::Null => Err(Error::invalid_ref("Arc cannot be null")),
143        RefFlag::Ref => {
144            let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
145            context
146                .ref_reader
147                .get_arc_ref::<T>(ref_id)
148                .ok_or_else(|| Error::invalid_ref(format!("Arc reference {ref_id} not found")))
149        }
150        RefFlag::NotNullValue => {
151            let inner = read_arc_inner::<T>(context, read_type_info, typeinfo)?;
152            Ok(Arc::new(inner))
153        }
154        RefFlag::RefValue => {
155            let ref_id = context.ref_reader.reserve_ref_id();
156            let inner = read_arc_inner::<T>(context, read_type_info, typeinfo)?;
157            let arc = Arc::new(inner);
158            context.ref_reader.store_arc_ref_at(ref_id, arc.clone());
159            Ok(arc)
160        }
161    }
162}
163
164fn read_arc_inner<T: Serializer + ForyDefault + 'static>(
165    context: &mut ReadContext,
166    read_type_info: bool,
167    typeinfo: Option<Rc<TypeInfo>>,
168) -> Result<T, Error> {
169    if let Some(typeinfo) = typeinfo {
170        let inner_read_ref = T::fory_is_shared_ref();
171        return T::fory_read_with_type_info(context, inner_read_ref, typeinfo);
172    }
173    if T::fory_is_shared_ref() || T::fory_is_polymorphic() {
174        let inner_read_ref = T::fory_is_shared_ref();
175        return T::fory_read(context, inner_read_ref, read_type_info);
176    }
177    if read_type_info {
178        T::fory_read_type_info(context)?;
179    }
180    T::fory_read_data(context)
181}
182
183impl<T: ForyDefault> ForyDefault for Arc<T> {
184    fn fory_default() -> Self {
185        Arc::new(T::fory_default())
186    }
187}