fory_core/serializer/
rc.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, RefMode, TypeId};
23use std::rc::Rc;
24
25impl<T: Serializer + ForyDefault + 'static> Serializer for Rc<T> {
26 fn fory_is_shared_ref() -> bool {
27 true
28 }
29
30 fn fory_write(
31 &self,
32 context: &mut WriteContext,
33 ref_mode: RefMode,
34 write_type_info: bool,
35 has_generics: bool,
36 ) -> Result<(), Error> {
37 match ref_mode {
38 RefMode::None => {
39 if write_type_info {
41 T::fory_write_type_info(context)?;
42 }
43 T::fory_write_data_generic(self, context, has_generics)
44 }
45 RefMode::NullOnly => {
46 context.writer.write_i8(RefFlag::NotNullValue as i8);
48 if write_type_info {
49 T::fory_write_type_info(context)?;
50 }
51 T::fory_write_data_generic(self, context, has_generics)
52 }
53 RefMode::Tracking => {
54 if context
56 .ref_writer
57 .try_write_rc_ref(&mut context.writer, self)
58 {
59 return Ok(());
61 }
62 if write_type_info {
64 T::fory_write_type_info(context)?;
65 }
66 T::fory_write_data_generic(self, context, has_generics)
67 }
68 }
69 }
70
71 fn fory_write_data_generic(
72 &self,
73 context: &mut WriteContext,
74 has_generics: bool,
75 ) -> Result<(), Error> {
76 if T::fory_is_shared_ref() {
77 return Err(Error::not_allowed(
78 "Rc<T> where T is a shared ref type is not allowed for serialization.",
79 ));
80 }
81 T::fory_write_data_generic(&**self, context, has_generics)
82 }
83
84 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
85 self.fory_write_data_generic(context, false)
86 }
87
88 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
89 T::fory_write_type_info(context)
90 }
91
92 fn fory_read(
93 context: &mut ReadContext,
94 ref_mode: RefMode,
95 read_type_info: bool,
96 ) -> Result<Self, Error> {
97 read_rc(context, ref_mode, read_type_info, None)
98 }
99
100 fn fory_read_with_type_info(
101 context: &mut ReadContext,
102 ref_mode: RefMode,
103 typeinfo: Rc<TypeInfo>,
104 ) -> Result<Self, Error>
105 where
106 Self: Sized + ForyDefault,
107 {
108 read_rc(context, ref_mode, false, Some(typeinfo))
109 }
110
111 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
112 if T::fory_is_shared_ref() {
113 return Err(Error::not_allowed(
114 "Rc<T> where T is a shared ref type is not allowed for deserialization.",
115 ));
116 }
117 let inner = T::fory_read_data(context)?;
118 Ok(Rc::new(inner))
119 }
120
121 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
122 T::fory_read_type_info(context)
123 }
124
125 fn fory_reserved_space() -> usize {
126 4
129 }
130
131 fn fory_get_type_id(type_resolver: &TypeResolver) -> Result<TypeId, Error> {
132 T::fory_get_type_id(type_resolver)
133 }
134
135 fn fory_get_type_info(type_resolver: &TypeResolver) -> Result<Rc<TypeInfo>, Error> {
136 match type_resolver.get_type_info(&std::any::TypeId::of::<T>()) {
137 Ok(info) => Ok(info),
138 Err(e) => Err(Error::enhance_type_error::<T>(e)),
139 }
140 }
141
142 fn fory_type_id_dyn(&self, type_resolver: &TypeResolver) -> Result<TypeId, Error> {
143 (**self).fory_type_id_dyn(type_resolver)
144 }
145
146 fn fory_static_type_id() -> TypeId {
147 T::fory_static_type_id()
148 }
149
150 fn as_any(&self) -> &dyn std::any::Any {
151 self
152 }
153}
154
155fn read_rc<T: Serializer + ForyDefault + 'static>(
156 context: &mut ReadContext,
157 ref_mode: RefMode,
158 read_type_info: bool,
159 typeinfo: Option<Rc<TypeInfo>>,
160) -> Result<Rc<T>, Error> {
161 match ref_mode {
162 RefMode::None => {
163 let inner = read_rc_inner::<T>(context, read_type_info, typeinfo)?;
165 Ok(Rc::new(inner))
166 }
167 RefMode::NullOnly => {
168 let ref_flag = context.reader.read_i8()?;
170 if ref_flag == RefFlag::Null as i8 {
171 return Err(Error::invalid_ref("Rc cannot be null"));
172 }
173 let inner = read_rc_inner::<T>(context, read_type_info, typeinfo)?;
174 Ok(Rc::new(inner))
175 }
176 RefMode::Tracking => {
177 let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader)?;
179 match ref_flag {
180 RefFlag::Null => Err(Error::invalid_ref("Rc cannot be null")),
181 RefFlag::Ref => {
182 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
183 context.ref_reader.get_rc_ref::<T>(ref_id).ok_or_else(|| {
184 Error::invalid_ref(format!("Rc reference {ref_id} not found"))
185 })
186 }
187 RefFlag::NotNullValue => {
188 let inner = read_rc_inner::<T>(context, read_type_info, typeinfo)?;
189 Ok(Rc::new(inner))
190 }
191 RefFlag::RefValue => {
192 let ref_id = context.ref_reader.reserve_ref_id();
193 let inner = read_rc_inner::<T>(context, read_type_info, typeinfo)?;
194 let rc = Rc::new(inner);
195 context.ref_reader.store_rc_ref_at(ref_id, rc.clone());
196 Ok(rc)
197 }
198 }
199 }
200 }
201}
202
203fn read_rc_inner<T: Serializer + ForyDefault + 'static>(
204 context: &mut ReadContext,
205 read_type_info: bool,
206 typeinfo: Option<Rc<TypeInfo>>,
207) -> Result<T, Error> {
208 if let Some(typeinfo) = typeinfo {
211 return T::fory_read_with_type_info(context, RefMode::None, typeinfo);
212 }
213 if read_type_info {
214 T::fory_read_type_info(context)?;
215 }
216 T::fory_read_data(context)
217}
218
219impl<T: ForyDefault> ForyDefault for Rc<T> {
220 fn fory_default() -> Self {
221 Rc::new(T::fory_default())
222 }
223}