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