fory_core/serializer/
unknown_case.rs1use crate::context::{ReadContext, WriteContext};
19use crate::error::Error;
20use crate::resolver::{RefFlag, RefMode};
21use crate::serializer::any::check_erased_any_payload_type;
22use crate::serializer::{ForyDefault, Serializer};
23use crate::type_id::{self, TypeId};
24use crate::types::UnknownCase;
25use std::any::Any;
26use std::sync::Arc;
27
28#[doc(hidden)]
29pub fn write_payload(context: &mut WriteContext, unknown: &UnknownCase) -> Result<(), Error> {
30 if write_typed_payload(context, unknown)? {
31 return Ok(());
32 }
33 unknown
34 .value_arc()
35 .fory_write(context, RefMode::Tracking, true, false)
36}
37
38fn write_typed_payload(context: &mut WriteContext, unknown: &UnknownCase) -> Result<bool, Error> {
39 let type_id = unknown.type_id();
40 if type_id == type_id::UNKNOWN && unknown.downcast_ref::<()>().is_some() {
41 context.writer.write_i8(RefFlag::Null as i8);
42 return Ok(true);
43 }
44 if !has_typed_value(unknown) {
45 return Ok(false);
46 }
47 context.writer.write_i8(RefFlag::NotNullValue as i8);
53 context.writer.write_u8(type_id as u8);
54 match type_id {
55 type_id::BOOL => context
56 .writer
57 .write_bool(*unknown.downcast_ref::<bool>().unwrap()),
58 type_id::INT8 => context
59 .writer
60 .write_i8(*unknown.downcast_ref::<i8>().unwrap()),
61 type_id::INT16 => context
62 .writer
63 .write_i16(*unknown.downcast_ref::<i16>().unwrap()),
64 type_id::INT32 => context
65 .writer
66 .write_i32(*unknown.downcast_ref::<i32>().unwrap()),
67 type_id::VARINT32 => context
68 .writer
69 .write_var_i32(*unknown.downcast_ref::<i32>().unwrap()),
70 type_id::INT64 => context
71 .writer
72 .write_i64(*unknown.downcast_ref::<i64>().unwrap()),
73 type_id::VARINT64 => context
74 .writer
75 .write_var_i64(*unknown.downcast_ref::<i64>().unwrap()),
76 type_id::TAGGED_INT64 => context
77 .writer
78 .write_tagged_i64(*unknown.downcast_ref::<i64>().unwrap()),
79 type_id::UINT8 => context
80 .writer
81 .write_u8(*unknown.downcast_ref::<u8>().unwrap()),
82 type_id::UINT16 => context
83 .writer
84 .write_u16(*unknown.downcast_ref::<u16>().unwrap()),
85 type_id::UINT32 => context
86 .writer
87 .write_u32(*unknown.downcast_ref::<u32>().unwrap()),
88 type_id::VAR_UINT32 => context
89 .writer
90 .write_var_u32(*unknown.downcast_ref::<u32>().unwrap()),
91 type_id::UINT64 => context
92 .writer
93 .write_u64(*unknown.downcast_ref::<u64>().unwrap()),
94 type_id::VAR_UINT64 => context
95 .writer
96 .write_var_u64(*unknown.downcast_ref::<u64>().unwrap()),
97 type_id::TAGGED_UINT64 => context
98 .writer
99 .write_tagged_u64(*unknown.downcast_ref::<u64>().unwrap()),
100 _ => return Ok(false),
101 }
102 Ok(true)
103}
104
105fn has_typed_value(unknown: &UnknownCase) -> bool {
106 match unknown.type_id() {
107 type_id::BOOL => unknown.downcast_ref::<bool>().is_some(),
108 type_id::INT8 => unknown.downcast_ref::<i8>().is_some(),
109 type_id::INT16 => unknown.downcast_ref::<i16>().is_some(),
110 type_id::INT32 | type_id::VARINT32 => unknown.downcast_ref::<i32>().is_some(),
111 type_id::INT64 | type_id::VARINT64 | type_id::TAGGED_INT64 => {
112 unknown.downcast_ref::<i64>().is_some()
113 }
114 type_id::UINT8 => unknown.downcast_ref::<u8>().is_some(),
115 type_id::UINT16 => unknown.downcast_ref::<u16>().is_some(),
116 type_id::UINT32 | type_id::VAR_UINT32 => unknown.downcast_ref::<u32>().is_some(),
117 type_id::UINT64 | type_id::VAR_UINT64 | type_id::TAGGED_UINT64 => {
118 unknown.downcast_ref::<u64>().is_some()
119 }
120 _ => false,
121 }
122}
123
124#[doc(hidden)]
125pub fn read_payload(context: &mut ReadContext, case_id: u32) -> Result<UnknownCase, Error> {
126 let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader)?;
127 match ref_flag {
128 RefFlag::Null => Ok(UnknownCase::new(case_id, ())),
129 RefFlag::Ref => {
130 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
131 let value = context
132 .ref_reader
133 .get_arc_ref::<dyn std::any::Any + Send + Sync>(ref_id)
134 .ok_or_else(|| {
135 Error::invalid_data(format!("UnknownCase ref {} not found", ref_id))
136 })?;
137 Ok(UnknownCase::from_runtime(
138 case_id,
139 TypeId::UNKNOWN as u32,
140 value,
141 ))
142 }
143 RefFlag::NotNullValue | RefFlag::RefValue => {
144 let ref_id = if matches!(ref_flag, RefFlag::RefValue) {
145 Some(context.ref_reader.reserve_ref_id())
149 } else {
150 None
151 };
152 let type_info = context.read_any_type_info()?;
157 check_erased_any_payload_type(&type_info)?;
158 let boxed = type_info
159 .get_harness()
160 .read_polymorphic_data_as_send_sync_any(context, &type_info)?;
161 let value: Arc<dyn std::any::Any + Send + Sync> = Arc::from(boxed);
162 if let Some(ref_id) = ref_id {
163 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
164 }
165 Ok(UnknownCase::from_runtime(
166 case_id,
167 type_info.get_type_id() as u32,
168 value,
169 ))
170 }
171 }
172}
173
174impl ForyDefault for UnknownCase {
175 fn fory_default() -> Self {
176 UnknownCase::new(0, ())
177 }
178}
179
180impl Serializer for UnknownCase {
181 fn fory_write(
182 &self,
183 context: &mut WriteContext,
184 ref_mode: RefMode,
185 write_type_info: bool,
186 _has_generics: bool,
187 ) -> Result<(), Error> {
188 let _ = ref_mode;
189 let _ = write_type_info;
190 write_payload(context, self)
191 }
192
193 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
194 write_payload(context, self)
195 }
196
197 fn fory_read(
198 context: &mut ReadContext,
199 ref_mode: RefMode,
200 read_type_info: bool,
201 ) -> Result<Self, Error> {
202 let _ = ref_mode;
203 let _ = read_type_info;
204 read_payload(context, 0)
205 }
206
207 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
208 read_payload(context, 0)
209 }
210 fn fory_read_data_as_send_sync_any(
211 context: &mut ReadContext,
212 ) -> Result<Box<dyn Any + Send + Sync>, Error> {
213 Ok(crate::serializer::box_send_sync(read_payload(context, 0)?))
214 }
215
216 fn fory_get_type_id(_: &crate::resolver::TypeResolver) -> Result<TypeId, Error> {
217 Ok(TypeId::UNKNOWN)
218 }
219
220 fn fory_type_id_dyn(
221 &self,
222 _type_resolver: &crate::resolver::TypeResolver,
223 ) -> Result<TypeId, Error> {
224 Ok(TypeId::UNKNOWN)
225 }
226
227 fn fory_static_type_id() -> TypeId {
228 TypeId::UNKNOWN
229 }
230
231 fn as_any(&self) -> &dyn Any {
232 self
233 }
234}