fory_core/serializer/
enum_.rs1use crate::ensure;
19use crate::error::Error;
20use crate::resolver::context::{ReadContext, WriteContext};
21use crate::serializer::{ForyDefault, Serializer};
22use crate::types::{RefFlag, TypeId};
23
24#[inline(always)]
25pub fn actual_type_id(type_id: u32, register_by_name: bool, _compatible: bool) -> u32 {
26 if register_by_name {
27 TypeId::NAMED_ENUM as u32
28 } else {
29 (type_id << 8) + TypeId::ENUM as u32
30 }
31}
32
33#[inline(always)]
34pub fn write<T: Serializer>(
35 this: &T,
36 context: &mut WriteContext,
37 write_ref_info: bool,
38 write_type_info: bool,
39) -> Result<(), Error> {
40 if write_ref_info {
41 context.writer.write_i8(RefFlag::NotNullValue as i8);
42 }
43 if write_type_info {
44 T::fory_write_type_info(context)?;
45 }
46 this.fory_write_data(context)
47}
48
49#[inline(always)]
50pub fn write_type_info<T: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
51 let type_id = T::fory_get_type_id(context.get_type_resolver())?;
52 context.writer.write_varuint32(type_id);
53 let is_named_enum = type_id & 0xff == TypeId::NAMED_ENUM as u32;
54 if !is_named_enum {
55 return Ok(());
56 }
57 let rs_type_id = std::any::TypeId::of::<T>();
58 if context.is_share_meta() {
59 let meta_index = context.push_meta(rs_type_id)? as u32;
60 context.writer.write_varuint32(meta_index);
61 } else {
62 let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
63 let namespace = type_info.get_namespace();
64 let type_name = type_info.get_type_name();
65 context.write_meta_string_bytes(namespace)?;
66 context.write_meta_string_bytes(type_name)?;
67 }
68 Ok(())
69}
70
71#[inline(always)]
72pub fn read<T: Serializer + ForyDefault>(
73 context: &mut ReadContext,
74 read_ref_info: bool,
75 read_type_info: bool,
76) -> Result<T, Error> {
77 let ref_flag = if read_ref_info {
78 context.reader.read_i8()?
79 } else {
80 RefFlag::NotNullValue as i8
81 };
82 if ref_flag == RefFlag::Null as i8 {
83 Ok(T::fory_default())
84 } else if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == (RefFlag::RefValue as i8) {
85 if read_type_info {
86 T::fory_read_type_info(context)?;
87 }
88 T::fory_read_data(context)
89 } else if ref_flag == (RefFlag::Ref as i8) {
90 Err(Error::invalid_ref("Invalid ref, enum type is not a ref"))
91 } else {
92 Err(Error::invalid_data(format!(
93 "Unknown ref flag: {}",
94 ref_flag
95 )))
96 }
97}
98
99#[inline(always)]
100pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
101 let local_type_id = T::fory_get_type_id(context.get_type_resolver())?;
102 let remote_type_id = context.reader.read_varuint32()?;
103 ensure!(
104 local_type_id == remote_type_id,
105 Error::type_mismatch(local_type_id, remote_type_id)
106 );
107 let is_named_enum = local_type_id & 0xff == TypeId::NAMED_ENUM as u32;
108 if !is_named_enum {
109 return Ok(());
110 }
111 if context.is_share_meta() {
112 let _meta_index = context.reader.read_varuint32()?;
113 } else {
114 let _namespace_msb = context.read_meta_string()?;
115 let _type_name_msb = context.read_meta_string()?;
116 }
117 Ok(())
118}