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