fory_core/serializer/
struct_.rs1use crate::context::{ReadContext, WriteContext};
19use crate::ensure;
20use crate::error::Error;
21use crate::resolver::{RefFlag, RefMode};
22use crate::serializer::{Serializer, StructSerializer};
23use crate::type_id::TypeId;
24use crate::util::ENABLE_FORY_DEBUG_OUTPUT;
25use std::any::Any;
26
27#[inline(always)]
28pub fn actual_type_id(_type_id: u32, register_by_name: bool, compatible: bool) -> u32 {
29 if compatible {
30 if register_by_name {
31 TypeId::NAMED_COMPATIBLE_STRUCT as u32
32 } else {
33 TypeId::COMPATIBLE_STRUCT as u32
34 }
35 } else if register_by_name {
36 TypeId::NAMED_STRUCT as u32
37 } else {
38 TypeId::STRUCT as u32
39 }
40}
41
42#[inline(always)]
43pub fn write_type_info<T: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
44 let rs_type_id = std::any::TypeId::of::<T>();
45 let type_id = T::fory_get_type_id(context.get_type_resolver())?;
46 context.write_any_type_info(type_id as u32, rs_type_id)?;
47 Ok(())
48}
49
50#[inline(always)]
51pub fn write_type_info_fast<T: StructSerializer>(context: &mut WriteContext) -> Result<(), Error> {
52 context.write_struct_type_info::<T>()
53}
54
55#[inline(always)]
56pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
57 context.read_any_type_info()?;
58 Ok(())
59}
60
61#[inline(always)]
62pub fn read_type_info_fast<T: StructSerializer>(context: &mut ReadContext) -> Result<(), Error> {
63 if context.is_compatible() || context.is_xlang() {
64 return read_type_info::<T>(context);
65 }
66 let local_type_id = context
67 .get_type_resolver()
68 .get_type_id_by_index(T::fory_type_index())?;
69 let local_type_id_u32 = local_type_id as u32;
70 if !crate::type_id::needs_user_type_id(local_type_id_u32) {
71 return read_type_info::<T>(context);
72 }
73 let remote_type_id = context.reader.read_u8()? as u32;
74 ensure!(
75 local_type_id_u32 == remote_type_id,
76 Error::type_mismatch(local_type_id_u32, remote_type_id)
77 );
78 let remote_user_type_id = context.reader.read_var_u32()?;
79 let local_user_type_id = context
80 .get_type_resolver()
81 .get_user_type_id_by_index(&std::any::TypeId::of::<T>(), T::fory_type_index())?;
82 if remote_user_type_id != local_user_type_id {
83 return Err(Error::type_error(format!(
84 "User type id mismatch: local {} vs remote {}",
85 local_user_type_id, remote_user_type_id
86 )));
87 }
88 Ok(())
89}
90
91#[inline(always)]
92pub fn write<T: Serializer>(
93 this: &T,
94 context: &mut WriteContext,
95 ref_mode: RefMode,
96 write_type_info: bool,
97) -> Result<(), Error> {
98 match ref_mode {
99 RefMode::None => {}
100 RefMode::NullOnly => {
101 context.writer.write_i8(RefFlag::NotNullValue as i8);
102 }
103 RefMode::Tracking => {
104 context.writer.write_i8(RefFlag::RefValue as i8);
107 context.ref_writer.reserve_ref_id();
108 }
109 }
110 if write_type_info {
111 T::fory_write_type_info(context)?;
112 }
113 this.fory_write_data(context)
114}
115
116pub type BeforeWriteFieldFunc =
117 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
118pub type AfterWriteFieldFunc =
119 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
120pub type BeforeReadFieldFunc = fn(struct_name: &str, field_name: &str, context: &mut ReadContext);
121pub type AfterReadFieldFunc =
122 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut ReadContext);
123
124fn default_before_write_field(
125 struct_name: &str,
126 field_name: &str,
127 _field_value: &dyn Any,
128 context: &mut WriteContext,
129) {
130 if ENABLE_FORY_DEBUG_OUTPUT {
131 println!(
132 "before_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
133 context.writer.len()
134 );
135 }
136}
137
138fn default_after_write_field(
139 struct_name: &str,
140 field_name: &str,
141 _field_value: &dyn Any,
142 context: &mut WriteContext,
143) {
144 if ENABLE_FORY_DEBUG_OUTPUT {
145 println!(
146 "after_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
147 context.writer.len()
148 );
149 }
150}
151
152fn default_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
153 if ENABLE_FORY_DEBUG_OUTPUT {
154 println!(
155 "before_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
156 context.reader.get_cursor()
157 );
158 }
159}
160
161fn default_after_read_field(
162 struct_name: &str,
163 field_name: &str,
164 _field_value: &dyn Any,
165 context: &mut ReadContext,
166) {
167 if ENABLE_FORY_DEBUG_OUTPUT {
168 println!(
169 "after_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
170 context.reader.get_cursor()
171 );
172 }
173}
174
175static mut BEFORE_WRITE_FIELD_FUNC: BeforeWriteFieldFunc = default_before_write_field;
176static mut AFTER_WRITE_FIELD_FUNC: AfterWriteFieldFunc = default_after_write_field;
177static mut BEFORE_READ_FIELD_FUNC: BeforeReadFieldFunc = default_before_read_field;
178static mut AFTER_READ_FIELD_FUNC: AfterReadFieldFunc = default_after_read_field;
179
180pub fn set_before_write_field_func(func: BeforeWriteFieldFunc) {
181 unsafe { BEFORE_WRITE_FIELD_FUNC = func }
182}
183
184pub fn set_after_write_field_func(func: AfterWriteFieldFunc) {
185 unsafe { AFTER_WRITE_FIELD_FUNC = func }
186}
187
188pub fn set_before_read_field_func(func: BeforeReadFieldFunc) {
189 unsafe { BEFORE_READ_FIELD_FUNC = func }
190}
191
192pub fn set_after_read_field_func(func: AfterReadFieldFunc) {
193 unsafe { AFTER_READ_FIELD_FUNC = func }
194}
195
196pub fn reset_struct_debug_hooks() {
197 unsafe {
198 BEFORE_WRITE_FIELD_FUNC = default_before_write_field;
199 AFTER_WRITE_FIELD_FUNC = default_after_write_field;
200 BEFORE_READ_FIELD_FUNC = default_before_read_field;
201 AFTER_READ_FIELD_FUNC = default_after_read_field;
202 }
203}
204
205pub fn struct_before_write_field(
207 struct_name: &str,
208 field_name: &str,
209 field_value: &dyn Any,
210 context: &mut WriteContext,
211) {
212 unsafe { BEFORE_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
213}
214
215pub fn struct_after_write_field(
217 struct_name: &str,
218 field_name: &str,
219 field_value: &dyn Any,
220 context: &mut WriteContext,
221) {
222 unsafe { AFTER_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
223}
224
225pub fn struct_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
227 unsafe { BEFORE_READ_FIELD_FUNC(struct_name, field_name, context) }
228}
229
230pub fn struct_after_read_field(
232 struct_name: &str,
233 field_name: &str,
234 field_value: &dyn Any,
235 context: &mut ReadContext,
236) {
237 unsafe { AFTER_READ_FIELD_FUNC(struct_name, field_name, field_value, context) }
238}