pi_sinfo/
lib.rs

1//! 用于描述`结构体`,即结构体的元信息
2//!
3//! 结构体类型包含下列几种信息:
4//! * 结构体的名称
5//! * 结构体的名称所计算出来的hash值
6//! * 结构体包含的字段
7//! * 结构体上包含的注解
8//!
9//! 其中,字段又被包含下列几种信息:
10//! * 字段名称
11//! * 字段类型
12//! * 字段上的注解
13//!
14//! 通常本库用于结构体数据的反序列化过程。StructInfo本身支持序列化成二进制,和反序列化。
15//! 一个结构体的实例,可以被序列化为一个十分紧凑的数据,在序列化过程中,可不含每个字段的类型。
16//! 当其被反序列化时,可以根据元信息中描述的字段类型,来反序列化
17//!
18
19extern crate pi_atom;
20extern crate pi_bon;
21
22use std::vec::Vec;
23use std::collections::HashMap;
24use std::sync::Arc;
25
26use pi_atom::Atom;
27use pi_bon::{WriteBuffer, ReadBuffer, Encode, Decode, ReadBonErr};
28
29/**
30* 自定义对象序列化元信息
31*/
32#[derive(Debug)]
33pub struct StructInfo {
34	pub name: Atom,
35	pub name_hash: u32,
36	pub notes: Option<HashMap<Atom, Atom>>,
37	pub fields: Vec<FieldInfo>,
38	pub is_ignore_name: bool,
39	pub is_ignore_name_hash: bool,
40	pub is_ignore_notes: bool,
41}
42
43impl PartialEq for StructInfo {
44	fn eq(&self, other: &Self) -> bool {
45		let is_ignore_name = self.is_ignore_name_hash || other.is_ignore_name_hash;
46		let is_ignore_name_hash = self.is_ignore_name_hash || other.is_ignore_name_hash;
47		let is_ignore_notes = self.is_ignore_notes || other.is_ignore_notes;
48
49		let mut result = true;
50		if !is_ignore_name {
51			result &= self.name.eq(&other.name);
52		}
53		if !is_ignore_name_hash {
54			result &= self.name_hash.eq(&other.name_hash);
55		}
56		if !is_ignore_notes {
57			result &= self.notes.eq(&other.notes);
58		}
59		result &= self.fields.eq(&other.fields);
60
61		result
62	}
63}
64
65impl StructInfo {
66	/**
67	* 构建自定义对象序列化元信息
68	* @param name 自定义对象名称
69	* @param name_hash 自定义对象名称hash
70	* @returns 返回自定义对象序列化元信息
71	*/
72	pub fn new(name:Atom, name_hash:u32) -> Self {
73		StructInfo {
74			name:name,
75			name_hash: name_hash,
76			notes: None,
77			fields: Vec::new(),
78			is_ignore_name: false,
79			is_ignore_name_hash: false,
80			is_ignore_notes: false,
81		}
82	}
83	pub fn get_note(&self, key: &Atom) -> Option<&Atom> {
84		match self.notes {
85			Some(ref map) => map.get(key),
86			_ => None
87		}
88	}
89}
90
91impl Encode for StructInfo{
92	fn encode(&self, bb: &mut WriteBuffer){
93		self.name.encode(bb);
94		self.name_hash.encode(bb);
95        self.notes.encode(bb);
96        self.fields.encode(bb);
97	}
98}
99
100impl Decode for StructInfo{
101	fn decode(bb: &mut ReadBuffer) -> Result<StructInfo, ReadBonErr> {
102		Ok(StructInfo{
103			name: Atom::decode(bb)?,
104			name_hash: u32::decode(bb)?,
105			notes: Option::decode(bb)?,
106			fields: Vec::decode(bb)?,
107			is_ignore_name: false,
108			is_ignore_name_hash: false,
109			is_ignore_notes: false,
110		})
111	}
112}
113
114// 枚举结构体字段的所有类型
115#[derive(Debug, Clone, PartialEq)]
116pub enum EnumType {
117	Bool,
118	U8,
119	U16,
120	U32,
121	U64,
122	U128,
123	U256,
124	Usize,
125	I8,
126	I16,
127	I32,
128	I64,
129	I128,
130	I256,
131	Isize,
132	F32,
133	F64,
134	BigI,
135	Str,
136	Bin,
137	Arr(Arc<EnumType>),
138	Map(Arc<EnumType>, Arc<EnumType>),
139	Struct(Arc<StructInfo>),
140	Option(Arc<EnumType>),
141	Enum(Arc<EnumInfo>)
142}
143
144impl Encode for EnumType{
145	fn encode(&self, bb:&mut WriteBuffer){
146		match self{
147			&EnumType::Bool => 0.encode(bb),
148			&EnumType::U8 => 1.encode(bb),
149			&EnumType::U16 => 2.encode(bb),
150			&EnumType::U32 => 3.encode(bb),
151			&EnumType::U64 => 4.encode(bb),
152			&EnumType::U128 => 5.encode(bb),
153			&EnumType::U256 => 6.encode(bb),
154			&EnumType::Usize => 7.encode(bb),
155			&EnumType::I8 => 8.encode(bb),
156			&EnumType::I16 => 9.encode(bb),
157			&EnumType::I32 => 10.encode(bb),
158			&EnumType::I64 => 11.encode(bb),
159			&EnumType::I128 => 12.encode(bb),
160			&EnumType::I256 => 13.encode(bb),
161			&EnumType::Isize => 14.encode(bb),
162			&EnumType::F32 => 15.encode(bb),
163			&EnumType::F64 => 16.encode(bb),
164			&EnumType::BigI => 17.encode(bb),
165			&EnumType::Str => 18.encode(bb),
166			&EnumType::Bin => 19.encode(bb),
167			&EnumType::Arr(ref v) => {20.encode(bb); v.encode(bb);},
168			&EnumType::Map(ref k, ref v) => {21.encode(bb); k.encode(bb); v.encode(bb);},
169			&EnumType::Struct(ref v) => {22.encode(bb); v.encode(bb);},
170			&EnumType::Option(ref v) => {23.encode(bb); v.encode(bb);},
171			&EnumType::Enum(ref v) => {24.encode(bb); v.encode(bb);},
172		};
173	}
174}
175
176impl Decode for EnumType{
177	fn decode(bb:&mut ReadBuffer) -> Result<EnumType, ReadBonErr> {
178		let t = u8::decode(bb)?;
179		match t{
180			0 => Ok(EnumType::Bool),
181			1 => Ok(EnumType::U8),
182			2 => Ok(EnumType::U16),
183			3 => Ok(EnumType::U32),
184			4 => Ok(EnumType::U64),
185			5 => Ok(EnumType::U128),
186			6 => Ok(EnumType::U256),
187			7 => Ok(EnumType::Usize),
188			8 => Ok(EnumType::I8),
189			9 => Ok(EnumType::I16),
190			10 => Ok(EnumType::I32),
191			11 => Ok(EnumType::I64),
192			12 => Ok(EnumType::I128),
193			13 => Ok(EnumType::I256),
194			14 => Ok(EnumType::Isize),
195			15 => Ok(EnumType::F32),
196			16 => Ok(EnumType::F64),
197			17 => Ok(EnumType::BigI),
198			18 => Ok(EnumType::Str),
199			19 => Ok(EnumType::Bin),
200			20 => Ok(EnumType::Arr(Arc::new(EnumType::decode(bb)?))),
201			21 => Ok(EnumType::Map(Arc::new(EnumType::decode(bb)?), Arc::new(EnumType::decode(bb)?))),
202			22 => Ok(EnumType::Struct(Arc::new(StructInfo::decode(bb)?))),
203			23 => Ok(EnumType::Option(Arc::new(EnumType::decode(bb)?))),
204			24 => Ok(EnumType::Enum(Arc::new(EnumInfo::decode(bb)?))),
205			_ => panic!("EnumType is not exist:{}", t)
206		}
207	}
208}
209
210#[derive(Debug)]
211pub struct FieldInfo {
212	pub name: Atom,
213	pub ftype: EnumType,
214	pub notes: Option<HashMap<Atom, Atom>>,
215	pub is_ignore_name: bool,
216	pub is_ignore_ftype: bool,
217	pub is_ignore_notes: bool,
218}
219
220impl PartialEq for FieldInfo {
221	fn eq(&self, other: &Self) -> bool {
222		let is_ignore_name = self.is_ignore_name || other.is_ignore_name;
223		let is_ignore_ftype = self.is_ignore_ftype || other.is_ignore_ftype;
224		let is_ignore_notes = self.is_ignore_notes || other.is_ignore_notes;
225
226		let mut result = true;
227		if !is_ignore_name {
228			result &= self.name.eq(&other.name);
229		}
230		if !is_ignore_ftype {
231			result &= self.ftype.eq(&other.ftype);
232		}
233		if !is_ignore_notes {
234			result &= self.notes.eq(&other.notes);
235		}
236
237		result
238	}
239}
240
241
242impl FieldInfo{
243	pub fn get_note(&self, key: &Atom) -> Option<&Atom> {
244		match self.notes {
245			Some(ref map) => map.get(key),
246			_ => None
247		}
248	}
249}
250impl Encode for FieldInfo{
251	fn encode(&self, bb: &mut WriteBuffer){
252		self.name.encode(bb);
253		self.ftype.encode(bb);
254		self.notes.encode(bb);
255	}
256}
257
258impl Decode for FieldInfo{
259	fn decode(bb: &mut ReadBuffer) -> Result<FieldInfo, ReadBonErr> {
260		let n = Atom::decode(bb)?;
261		Ok(FieldInfo{
262			name: n,
263			ftype: EnumType::decode(bb)?,
264			notes: Option::decode(bb)?,
265			is_ignore_name: false,
266			is_ignore_ftype: false,
267			is_ignore_notes: false,
268		})
269	}
270}
271
272#[derive(Debug, PartialEq)]
273pub struct EnumInfo {
274	pub name: Atom,
275	pub name_hash: u32,
276	pub notes: Option<HashMap<Atom, Atom>>,
277	pub members: Vec<Option<EnumType>>,
278}
279
280impl EnumInfo {
281	pub fn new(name:Atom, name_hash:u32) -> Self {
282		EnumInfo {
283			name:name,
284			name_hash: name_hash,
285			notes: None,
286			members: Vec::new(),
287		}
288	}
289}
290
291impl Encode for EnumInfo{
292	fn encode(&self, bb: &mut WriteBuffer){
293		self.name.encode(bb);
294		self.name_hash.encode(bb);
295        self.notes.encode(bb);
296        self.members.encode(bb);
297	}
298}
299
300impl Decode for EnumInfo{
301	fn decode(bb: &mut ReadBuffer) -> Result<EnumInfo, ReadBonErr>{
302		let n = Atom::decode(bb)?;
303		Ok(EnumInfo{
304			name: n,
305			name_hash: u32::decode(bb)?,
306			notes: Option::decode(bb)?,
307			members: Vec::decode(bb)?,
308		})
309	}
310}
311