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 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 (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
107pub type BeforeWriteFieldFunc =
108 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
109pub type AfterWriteFieldFunc =
110 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut WriteContext);
111pub type BeforeReadFieldFunc = fn(struct_name: &str, field_name: &str, context: &mut ReadContext);
112pub type AfterReadFieldFunc =
113 fn(struct_name: &str, field_name: &str, field_value: &dyn Any, context: &mut ReadContext);
114
115fn default_before_write_field(
116 struct_name: &str,
117 field_name: &str,
118 _field_value: &dyn Any,
119 context: &mut WriteContext,
120) {
121 if ENABLE_FORY_DEBUG_OUTPUT {
122 println!(
123 "before_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
124 context.writer.len()
125 );
126 }
127}
128
129fn default_after_write_field(
130 struct_name: &str,
131 field_name: &str,
132 _field_value: &dyn Any,
133 context: &mut WriteContext,
134) {
135 if ENABLE_FORY_DEBUG_OUTPUT {
136 println!(
137 "after_write_field:\tstruct={struct_name},\tfield={field_name},\twriter_len={}",
138 context.writer.len()
139 );
140 }
141}
142
143fn default_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
144 if ENABLE_FORY_DEBUG_OUTPUT {
145 println!(
146 "before_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
147 context.reader.get_cursor()
148 );
149 }
150}
151
152fn default_after_read_field(
153 struct_name: &str,
154 field_name: &str,
155 _field_value: &dyn Any,
156 context: &mut ReadContext,
157) {
158 if ENABLE_FORY_DEBUG_OUTPUT {
159 println!(
160 "after_read_field:\tstruct={struct_name},\tfield={field_name},\treader_cursor={}",
161 context.reader.get_cursor()
162 );
163 }
164}
165
166static mut BEFORE_WRITE_FIELD_FUNC: BeforeWriteFieldFunc = default_before_write_field;
167static mut AFTER_WRITE_FIELD_FUNC: AfterWriteFieldFunc = default_after_write_field;
168static mut BEFORE_READ_FIELD_FUNC: BeforeReadFieldFunc = default_before_read_field;
169static mut AFTER_READ_FIELD_FUNC: AfterReadFieldFunc = default_after_read_field;
170
171pub fn set_before_write_field_func(func: BeforeWriteFieldFunc) {
172 unsafe { BEFORE_WRITE_FIELD_FUNC = func }
173}
174
175pub fn set_after_write_field_func(func: AfterWriteFieldFunc) {
176 unsafe { AFTER_WRITE_FIELD_FUNC = func }
177}
178
179pub fn set_before_read_field_func(func: BeforeReadFieldFunc) {
180 unsafe { BEFORE_READ_FIELD_FUNC = func }
181}
182
183pub fn set_after_read_field_func(func: AfterReadFieldFunc) {
184 unsafe { AFTER_READ_FIELD_FUNC = func }
185}
186
187pub fn reset_struct_debug_hooks() {
188 unsafe {
189 BEFORE_WRITE_FIELD_FUNC = default_before_write_field;
190 AFTER_WRITE_FIELD_FUNC = default_after_write_field;
191 BEFORE_READ_FIELD_FUNC = default_before_read_field;
192 AFTER_READ_FIELD_FUNC = default_after_read_field;
193 }
194}
195
196pub fn struct_before_write_field(
198 struct_name: &str,
199 field_name: &str,
200 field_value: &dyn Any,
201 context: &mut WriteContext,
202) {
203 unsafe { BEFORE_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
204}
205
206pub fn struct_after_write_field(
208 struct_name: &str,
209 field_name: &str,
210 field_value: &dyn Any,
211 context: &mut WriteContext,
212) {
213 unsafe { AFTER_WRITE_FIELD_FUNC(struct_name, field_name, field_value, context) }
214}
215
216pub fn struct_before_read_field(struct_name: &str, field_name: &str, context: &mut ReadContext) {
218 unsafe { BEFORE_READ_FIELD_FUNC(struct_name, field_name, context) }
219}
220
221pub fn struct_after_read_field(
223 struct_name: &str,
224 field_name: &str,
225 field_value: &dyn Any,
226 context: &mut ReadContext,
227) {
228 unsafe { AFTER_READ_FIELD_FUNC(struct_name, field_name, field_value, context) }
229}