fory_core/serializer/
struct_.rs1use crate::ensure;
19use crate::error::Error;
20use crate::resolver::context::{ReadContext, WriteContext};
21use crate::serializer::Serializer;
22use crate::types::{RefFlag, TypeId};
23use std::any::Any;
24use std::sync::OnceLock;
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 (type_id << 8) + TypeId::COMPATIBLE_STRUCT as u32
33 }
34 } else if register_by_name {
35 TypeId::NAMED_STRUCT as u32
36 } else {
37 (type_id << 8) + TypeId::STRUCT as u32
38 }
39}
40
41#[inline(always)]
42pub fn write_type_info<T: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
43 let type_id = T::fory_get_type_id(context.get_type_resolver())?;
44 context.writer.write_varuint32(type_id);
45 let rs_type_id = std::any::TypeId::of::<T>();
46
47 if type_id & 0xff == TypeId::NAMED_STRUCT as u32 {
48 if context.is_share_meta() {
49 let meta_index = context.push_meta(rs_type_id)? as u32;
50 context.writer.write_varuint32(meta_index);
51 } else {
52 let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
53 let namespace = type_info.get_namespace();
54 let type_name = type_info.get_type_name();
55 context.write_meta_string_bytes(namespace)?;
56 context.write_meta_string_bytes(type_name)?;
57 }
58 } else if type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
59 || type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32
60 {
61 let meta_index = context.push_meta(rs_type_id)? as u32;
62 context.writer.write_varuint32(meta_index);
63 }
64 Ok(())
65}
66
67#[inline(always)]
68pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
69 let remote_type_id = context.reader.read_varuint32()?;
70 let local_type_id = T::fory_get_type_id(context.get_type_resolver())?;
71 ensure!(
72 local_type_id == remote_type_id,
73 Error::type_mismatch(local_type_id, remote_type_id)
74 );
75
76 if local_type_id & 0xff == TypeId::NAMED_STRUCT as u32 {
77 if context.is_share_meta() {
78 let _meta_index = context.reader.read_varuint32()?;
79 } else {
80 let _namespace_msb = context.read_meta_string()?;
81 let _type_name_msb = context.read_meta_string()?;
82 }
83 } else if local_type_id & 0xff == TypeId::NAMED_COMPATIBLE_STRUCT as u32
84 || local_type_id & 0xff == TypeId::COMPATIBLE_STRUCT as u32
85 {
86 let _meta_index = context.reader.read_varuint32();
87 }
88 Ok(())
89}
90
91#[inline(always)]
92pub fn write<T: Serializer>(
93 this: &T,
94 context: &mut WriteContext,
95 write_ref_info: bool,
96 write_type_info: bool,
97) -> Result<(), Error> {
98 if write_ref_info {
99 context.writer.write_i8(RefFlag::NotNullValue as i8);
100 }
101 if write_type_info {
102 T::fory_write_type_info(context)?;
103 }
104 this.fory_write_data(context)
105}
106
107static ENABLE_FORY_DEBUG_OUTPUT: OnceLock<bool> = OnceLock::new();
109
110#[inline]
112fn enable_debug_output() -> bool {
113 *ENABLE_FORY_DEBUG_OUTPUT.get_or_init(|| {
114 std::env::var("ENABLE_FORY_DEBUG_OUTPUT")
115 .map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
116 .unwrap_or(false)
117 })
118}
119
120pub type BeforeWriteFieldFunc =
121 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
122pub type AfterWriteFieldFunc =
123 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
124pub type BeforeReadFieldFunc = fn(struct_name: &str, field_name: &str, context: &mut ReadContext);
125pub type AfterReadFieldFunc =
126 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut ReadContext);
127
128fn default_before_write_field(
129 struct_name: &str,
130 field_name: &str,
131 _field_value: &dyn Any,
132 context: &mut WriteContext,
133) {
134 if enable_debug_output() {
135 println!(
136 "before_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
137 context.writer.len()
138 );
139 }
140}
141
142fn default_after_write_field(
143 struct_name: &str,
144 field_name: &str,
145 _field_value: &dyn Any,
146 context: &mut WriteContext,
147) {
148 if enable_debug_output() {
149 println!(
150 "after_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
151 context.writer.len()
152 );
153 }
154}
155
156fn default_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
157 if enable_debug_output() {
158 println!(
159 "before_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
160 context.reader.get_cursor()
161 );
162 }
163}
164
165fn default_after_read_field(
166 struct_name: &str,
167 field_name: &str,
168 _field_value: &dyn Any,
169 context: &mut ReadContext,
170) {
171 if enable_debug_output() {
172 println!(
173 "after_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
174 context.reader.get_cursor()
175 );
176 }
177}
178
179static mut BEFORE_WRITE_FIELD_FUNC: BeforeWriteFieldFunc = default_before_write_field;
180static mut AFTER_WRITE_FIELD_FUNC: AfterWriteFieldFunc = default_after_write_field;
181static mut BEFORE_READ_FIELD_FUNC: BeforeReadFieldFunc = default_before_read_field;
182static mut AFTER_READ_FIELD_FUNC: AfterReadFieldFunc = default_after_read_field;
183
184pub fn set_before_write_field_func(func: BeforeWriteFieldFunc) {
185 unsafe { BEFORE_WRITE_FIELD_FUNC = func }
186}
187
188pub fn set_after_write_field_func(func: AfterWriteFieldFunc) {
189 unsafe { AFTER_WRITE_FIELD_FUNC = func }
190}
191
192pub fn set_before_read_field_func(func: BeforeReadFieldFunc) {
193 unsafe { BEFORE_READ_FIELD_FUNC = func }
194}
195
196pub fn set_after_read_field_func(func: AfterReadFieldFunc) {
197 unsafe { AFTER_READ_FIELD_FUNC = func }
198}
199
200pub fn reset_struct_debug_hooks() {
201 unsafe {
202 BEFORE_WRITE_FIELD_FUNC = default_before_write_field;
203 AFTER_WRITE_FIELD_FUNC = default_after_write_field;
204 BEFORE_READ_FIELD_FUNC = default_before_read_field;
205 AFTER_READ_FIELD_FUNC = default_after_read_field;
206 }
207}
208
209pub fn struct_before_write_field(
211 struct_name: &str,
212 field_name: &str,
213 field_value: &dyn Any,
214 context: &mut WriteContext,
215) {
216 unsafe { BEFORE_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
217}
218
219pub fn struct_after_write_field(
221 struct_name: &str,
222 field_name: &str,
223 field_value: &dyn Any,
224 context: &mut WriteContext,
225) {
226 unsafe { AFTER_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
227}
228
229pub fn struct_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
231 unsafe { BEFORE_READ_FIELD_FUNC(struct_name, field_name, context) }
232}
233
234pub fn struct_after_read_field(
236 struct_name: &str,
237 field_name: &str,
238 field_value: &dyn Any,
239 context: &mut ReadContext,
240) {
241 unsafe { AFTER_READ_FIELD_FUNC(struct_name, field_name, field_value, context) }
242}