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