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_target_type;
22use crate::serializer::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_unknown_case_body(
30 context: &mut WriteContext,
31 unknown: &UnknownCase,
32) -> Result<(), Error> {
33 if write_typed_unknown_case_body(context, unknown)? {
34 return Ok(());
35 }
36 <Arc<dyn Any + Send + Sync> as Serializer>::write(
37 unknown.value_arc(),
38 context,
39 RefMode::Tracking,
40 true,
41 )
42}
43
44fn write_typed_unknown_case_body(
45 context: &mut WriteContext,
46 unknown: &UnknownCase,
47) -> Result<bool, Error> {
48 let type_id = unknown.type_id();
49 if type_id == type_id::UNKNOWN && unknown.downcast_ref::<()>().is_some() {
50 context.writer.write_i8(RefFlag::Null as i8);
51 return Ok(true);
52 }
53 if !has_typed_value(unknown) {
54 return Ok(false);
55 }
56 context.writer.write_i8(RefFlag::NotNullValue as i8);
62 context.writer.write_u8(type_id as u8);
63 match type_id {
64 type_id::BOOL => context
65 .writer
66 .write_bool(*unknown.downcast_ref::<bool>().unwrap()),
67 type_id::INT8 => context
68 .writer
69 .write_i8(*unknown.downcast_ref::<i8>().unwrap()),
70 type_id::INT16 => context
71 .writer
72 .write_i16(*unknown.downcast_ref::<i16>().unwrap()),
73 type_id::INT32 => context
74 .writer
75 .write_i32(*unknown.downcast_ref::<i32>().unwrap()),
76 type_id::VARINT32 => context
77 .writer
78 .write_var_i32(*unknown.downcast_ref::<i32>().unwrap()),
79 type_id::INT64 => context
80 .writer
81 .write_i64(*unknown.downcast_ref::<i64>().unwrap()),
82 type_id::VARINT64 => context
83 .writer
84 .write_var_i64(*unknown.downcast_ref::<i64>().unwrap()),
85 type_id::TAGGED_INT64 => context
86 .writer
87 .write_tagged_i64(*unknown.downcast_ref::<i64>().unwrap()),
88 type_id::UINT8 => context
89 .writer
90 .write_u8(*unknown.downcast_ref::<u8>().unwrap()),
91 type_id::UINT16 => context
92 .writer
93 .write_u16(*unknown.downcast_ref::<u16>().unwrap()),
94 type_id::UINT32 => context
95 .writer
96 .write_u32(*unknown.downcast_ref::<u32>().unwrap()),
97 type_id::VAR_UINT32 => context
98 .writer
99 .write_var_u32(*unknown.downcast_ref::<u32>().unwrap()),
100 type_id::UINT64 => context
101 .writer
102 .write_u64(*unknown.downcast_ref::<u64>().unwrap()),
103 type_id::VAR_UINT64 => context
104 .writer
105 .write_var_u64(*unknown.downcast_ref::<u64>().unwrap()),
106 type_id::TAGGED_UINT64 => context
107 .writer
108 .write_tagged_u64(*unknown.downcast_ref::<u64>().unwrap()),
109 _ => return Ok(false),
110 }
111 Ok(true)
112}
113
114fn has_typed_value(unknown: &UnknownCase) -> bool {
115 match unknown.type_id() {
116 type_id::BOOL => unknown.downcast_ref::<bool>().is_some(),
117 type_id::INT8 => unknown.downcast_ref::<i8>().is_some(),
118 type_id::INT16 => unknown.downcast_ref::<i16>().is_some(),
119 type_id::INT32 | type_id::VARINT32 => unknown.downcast_ref::<i32>().is_some(),
120 type_id::INT64 | type_id::VARINT64 | type_id::TAGGED_INT64 => {
121 unknown.downcast_ref::<i64>().is_some()
122 }
123 type_id::UINT8 => unknown.downcast_ref::<u8>().is_some(),
124 type_id::UINT16 => unknown.downcast_ref::<u16>().is_some(),
125 type_id::UINT32 | type_id::VAR_UINT32 => unknown.downcast_ref::<u32>().is_some(),
126 type_id::UINT64 | type_id::VAR_UINT64 | type_id::TAGGED_UINT64 => {
127 unknown.downcast_ref::<u64>().is_some()
128 }
129 _ => false,
130 }
131}
132
133#[doc(hidden)]
134pub fn read_unknown_case_body(
135 context: &mut ReadContext,
136 case_id: u32,
137) -> Result<UnknownCase, Error> {
138 let ref_flag = context.ref_reader.read_ref_flag(&mut context.reader)?;
139 match ref_flag {
140 RefFlag::Null => Ok(UnknownCase::new(case_id, ())),
141 RefFlag::Ref => {
142 let ref_id = context.ref_reader.read_ref_id(&mut context.reader)?;
143 let value = context
144 .ref_reader
145 .get_arc_ref::<dyn std::any::Any + Send + Sync>(ref_id)
146 .ok_or_else(|| {
147 Error::invalid_data(format!("UnknownCase ref {} not found", ref_id))
148 })?;
149 Ok(UnknownCase::from_runtime(
150 case_id,
151 TypeId::UNKNOWN as u32,
152 value,
153 ))
154 }
155 RefFlag::NotNullValue | RefFlag::RefValue => {
156 let ref_id = if matches!(ref_flag, RefFlag::RefValue) {
157 Some(context.ref_reader.reserve_ref_id())
161 } else {
162 None
163 };
164 let type_info = context.read_any_type_info()?;
169 check_erased_target_type(&type_info)?;
170 let value = type_info.get_harness().read_arc_any(context, &type_info)?;
171 if let Some(ref_id) = ref_id {
172 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
173 }
174 Ok(UnknownCase::from_runtime(
175 case_id,
176 type_info.get_type_id() as u32,
177 value,
178 ))
179 }
180 }
181}
182
183impl Serializer for UnknownCase {
184 type Target = Self;
185
186 fn write(
187 value: &Self,
188 context: &mut WriteContext,
189 ref_mode: RefMode,
190 write_type_info: bool,
191 ) -> Result<(), Error> {
192 let _ = ref_mode;
193 let _ = write_type_info;
194 write_unknown_case_body(context, value)
195 }
196
197 fn write_data(value: &Self, context: &mut WriteContext) -> Result<(), Error> {
198 write_unknown_case_body(context, value)
199 }
200
201 fn read(
202 context: &mut ReadContext,
203 ref_mode: RefMode,
204 read_type_info: bool,
205 ) -> Result<Self, Error> {
206 let _ = ref_mode;
207 let _ = read_type_info;
208 read_unknown_case_body(context, 0)
209 }
210
211 fn read_data(context: &mut ReadContext) -> Result<Self, Error> {
212 read_unknown_case_body(context, 0)
213 }
214
215 fn default_value(_: &mut ReadContext) -> Result<Self, Error> {
216 Ok(UnknownCase::new(0, ()))
217 }
218
219 fn read_arc_any(context: &mut ReadContext) -> Result<Arc<dyn Any + Send + Sync>, Error> {
220 Ok(Arc::new(read_unknown_case_body(context, 0)?))
221 }
222
223 fn static_type_id() -> TypeId {
224 TypeId::UNKNOWN
225 }
226}