fory_core/serializer/
enum_.rs1use crate::context::{ReadContext, WriteContext};
19use crate::ensure;
20use crate::error::Error;
21use crate::meta::FieldInfo;
22use crate::resolver::{RefFlag, RefMode, TypeResolver};
23use crate::serializer::{ForyDefault, Serializer};
24use crate::type_id::TypeId;
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.writer.write_var_u32(type_info.get_user_type_id());
59 return Ok(());
60 }
61 if context.is_share_meta() {
62 context.write_type_meta(rs_type_id)?;
64 } else {
65 let type_info = context.get_type_resolver().get_type_info(&rs_type_id)?;
66 let namespace = type_info.get_namespace();
67 let type_name = type_info.get_type_name();
68 context.write_meta_string_bytes(namespace)?;
69 context.write_meta_string_bytes(type_name)?;
70 }
71 Ok(())
72}
73
74#[inline(always)]
75pub fn read<T: Serializer + ForyDefault>(
76 context: &mut ReadContext,
77 ref_mode: RefMode,
78 read_type_info: bool,
79) -> Result<T, Error> {
80 let ref_flag = if ref_mode != RefMode::None {
81 context.reader.read_i8()?
82 } else {
83 RefFlag::NotNullValue as i8
84 };
85 if ref_flag == RefFlag::Null as i8 {
86 Ok(T::fory_default())
87 } else if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == (RefFlag::RefValue as i8) {
88 if read_type_info {
89 T::fory_read_type_info(context)?;
90 }
91 T::fory_read_data(context)
92 } else if ref_flag == (RefFlag::Ref as i8) {
93 Err(Error::invalid_ref("Invalid ref, enum type is not a ref"))
94 } else {
95 Err(Error::invalid_data(format!(
96 "Unknown ref flag: {}",
97 ref_flag
98 )))
99 }
100}
101
102#[inline(always)]
103pub fn read_type_info<T: Serializer>(context: &mut ReadContext) -> Result<(), Error> {
104 let local_type_id = T::fory_get_type_id(context.get_type_resolver())?;
105 let remote_type_id = context.reader.read_u8()?;
106 ensure!(
107 local_type_id as u8 == remote_type_id,
108 Error::type_mismatch(local_type_id as u32, remote_type_id as u32)
109 );
110 if remote_type_id == TypeId::NAMED_ENUM as u8 {
111 if context.is_share_meta() {
112 let _type_info = context.read_type_meta()?;
114 } else {
115 let _namespace_msb = context.read_meta_string()?;
116 let _type_name_msb = context.read_meta_string()?;
117 }
118 } else {
119 context.reader.read_var_u32()?;
120 }
121 Ok(())
122}
123
124pub trait NamedEnumVariantMetaTrait: 'static {
125 fn fory_get_sorted_field_names() -> &'static [&'static str] {
126 &[]
127 }
128
129 #[allow(unused_variables)]
130 fn fory_fields_info(type_resolver: &TypeResolver) -> Result<Vec<FieldInfo>, Error> {
131 Ok(Vec::default())
132 }
133}