fory_core/serializer/
arc.rs1use 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 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 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}