fory_core/serializer/
enum_.rs1use crate::ensure;
19use crate::error::Error;
20use crate::meta::FieldInfo;
21use crate::resolver::context::{ReadContext, WriteContext};
22use crate::serializer::{ForyDefault, Serializer};
23use crate::types::{RefFlag, RefMode, TypeId};
24use crate::TypeResolver;
25
26#[inline(always)]
27pub fn actual_type_id(_type_id: u32, register_by_name: bool, _compatible: bool) -> u32 {
28 if register_by_name {
29 TypeId::NAMED_ENUM as u32
30 } else {
31 TypeId::ENUM as u32
32 }
33}
34
35#[inline(always)]
36pub fn write<T: Serializer>(
37 this: &T,
38 context: &mut WriteContext,
39 ref_mode: RefMode,
40 write_type_info: bool,
41) -> Result<(), Error> {
42 if ref_mode != RefMode::None {
43 context.writer.write_i8(RefFlag::NotNullValue as i8);
44 }
45 if write_type_info {
46 T::fory_write_type_info(context)?;
47 }
48 this.fory_write_data(context)
49}
50
51#[inline(always)]
52pub fn write_type_info<T: Serializer>(context: &mut WriteContext) -> Result<(), Error> {
53 let type_id = T::fory_get_type_id(context.get_type_resolver())?;
54 context.writer.write_u8(type_id as u8);
55 let rs_type_id = std::any::TypeId::of::<T>();
56 if type_id == TypeId::ENUM {
57 let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
58 context
59 .writer
60 .write_var_uint32(type_info.get_user_type_id());
61 return Ok(());
62 }
63 if context.is_share_meta() {
64 context.write_type_meta(rs_type_id)?;
66 } else {
67 let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
68 let namespace = type_info.get_namespace();
69 let type_name = type_info.get_type_name();
70 context.write_meta_string_bytes(namespace)?;
71 context.write_meta_string_bytes(type_name)?;
72 }
73 Ok(())
74}
75
76#[inline(always)]
77pub fn read<T: Serializer + ForyDefault>(
78 context: &mut ReadContext,
79 ref_mode: RefMode,
80 read_type_info: bool,
81) -> Result<T, Error> {
82 let ref_flag = if ref_mode != RefMode::None {
83 context.reader.read_i8()?
84 } else {
85 RefFlag::NotNullValue as i8
86 };
87 if ref_flag == RefFlag::Null as i8 {
88 Ok(T::fory_default())
89 } else if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == (RefFlag::RefValue as i8) {
90 if read_type_info {
91 T::fory_read_type_info(context)?;
92 }
93 T::fory_read_data(context)
94 } else if ref_flag == (RefFlag::Ref as i8) {
95 Err(Error::invalid_ref("Invalid ref, enum type is not a ref"))
96 } else {
97 Err(Error::invalid_data(format!(
98 "Unknown ref flag: {}",
99 ref_flag
100 )))
101 }
102}
103
104#[inline(always)]
105pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
106 let local_type_id = T::fory_get_type_id(context.get_type_resolver())?;
107 let remote_type_id = context.reader.read_u8()?;
108 ensure!(
109 local_type_id as u8 == remote_type_id,
110 Error::type_mismatch(local_type_id as u32, remote_type_id as u32)
111 );
112 if remote_type_id == TypeId::NAMED_ENUM as u8 {
113 if context.is_share_meta() {
114 let _type_info = context.read_type_meta()?;
116 } else {
117 let _namespace_msb = context.read_meta_string()?;
118 let _type_name_msb = context.read_meta_string()?;
119 }
120 } else {
121 context.reader.read_varuint32()?;
122 }
123 Ok(())
124}
125
126pub trait NamedEnumVariantMetaTrait: 'static {
127 fn fory_get_sorted_field_names() -> &'static [&'static str] {
128 &[]
129 }
130
131 #[allow(unused_variables)]
132 fn fory_fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error> {
133 Ok(Vec::default())
134 }
135}