afastdata_core/lib.rs
1//! # afastdata-core
2//!
3//! afastdata 序列化框架的核心库,提供序列化/反序列化 trait 定义以及所有内置类型的实现。
4//!
5//! Core library for the afastdata serialization framework, providing trait definitions
6//! for serialization/deserialization and built-in implementations for all primitive types.
7//!
8//! ## 序列化编码规则 / Serialization Encoding Rules
9//!
10//! | 类型 / Type | 编码方式 / Encoding |
11//! |---|---|
12//! | `i8`, `u8` | 1 字节 little-endian / 1 byte little-endian |
13//! | `i16`, `u16` | 2 字节 little-endian / 2 bytes little-endian |
14//! | `i32`, `u32` | 4 字节 little-endian / 4 bytes little-endian |
15//! | `i64`, `u64` | 8 字节 little-endian / 8 bytes little-endian |
16//! | `i128`, `u128` | 16 字节 little-endian / 16 bytes little-endian |
17//! | `f32` | 4 字节 IEEE 754 / 4 bytes IEEE 754 |
18//! | `f64` | 8 字节 IEEE 754 / 8 bytes IEEE 754 |
19//! | `bool` | 1 字节,`0x00`=false,`0x01`=true / 1 byte, `0x00`=false, `0x01`=true |
20//! | `String` | 长度前缀 (LenInt) + UTF-8 字节 / Length prefix (LenInt) + UTF-8 bytes |
21//! | `Vec<T>` | 长度前缀 (LenInt) + 逐元素编码 / Length prefix (LenInt) + element-wise encoding |
22//! | `Option<T>` | 标记字节 (`0x00`=None, `0x01`=Some) + 数据(仅 Some 时)/ Tag byte (`0x00`=None, `0x01`=Some) + data (only when Some) |
23//! | `[T; N]` | 逐元素编码,无长度前缀 / Element-wise encoding, no length prefix |
24//! | `&str` | 长度前缀 (LenInt) + UTF-8 字节(仅序列化)/ Length prefix (LenInt) + UTF-8 bytes (serialize only) |
25//!
26//! ## 长度前缀类型 / Length Prefix Type
27//!
28//! 默认使用 `u32` 作为长度前缀(最大 4GB),可通过启用 `len-u64` feature 切换为 `u64`。
29//!
30//! By default, `u32` is used as the length prefix (max 4GB). Enable the `len-u64`
31//! feature to switch to `u64`.
32
33mod error;
34
35pub use error::{Error, ValidateError};
36
37/// 长度前缀使用的整数类型。默认为 `u32`,启用 `len-u64` feature 后为 `u64`。
38///
39/// The integer type used for length prefixes. Defaults to `u32`, switches to `u64`
40/// when the `len-u64` feature is enabled.
41#[cfg(feature = "len-u64")]
42pub type LenInt = u64;
43
44/// 长度前缀使用的整数类型。默认为 `u32`,启用 `len-u64` feature 后为 `u64`。
45///
46/// The integer type used for length prefixes. Defaults to `u32`, switches to `u64`
47/// when the `len-u64` feature is enabled.
48#[cfg(not(feature = "len-u64"))]
49pub type LenInt = u32;
50
51/// 长度前缀类型的字节大小(`u32` 为 4,`u64` 为 8)。
52///
53/// The byte size of the length prefix type (`4` for `u32`, `8` for `u64`).
54pub const LEN_INT_SIZE: usize = std::mem::size_of::<LenInt>();
55
56/// 序列化 trait,为类型提供转换为字节数组的能力。
57///
58/// Serialization trait that provides the ability to convert a type into a byte array.
59///
60/// # 编码规则 / Encoding Rules
61///
62/// 实现者应确保 `to_bytes()` 输出的字节流能够被对应的 [`AFastDeserialize::from_bytes`]
63/// 完整还原。字节序统一使用 **小端序 (little-endian)**。
64///
65/// Implementors must ensure that the byte output of `to_bytes()` can be fully
66/// restored by the corresponding [`AFastDeserialize::from_bytes`]. All multi-byte
67/// values use **little-endian** byte order.
68///
69/// # 示例 / Example
70///
71/// ```ignore
72/// use afastdata::AFastSerialize;
73///
74/// let value: i32 = 42;
75/// let bytes = value.to_bytes();
76/// assert_eq!(bytes, vec![42, 0, 0, 0]);
77/// ```
78pub trait AFastSerialize {
79 /// 将值序列化为字节数组。
80 ///
81 /// Serialize the value into a byte array.
82 ///
83 /// # 返回值 / Returns
84 ///
85 /// 返回一个 `Vec<u8>`,包含该值的完整二进制表示。
86 ///
87 /// Returns a `Vec<u8>` containing the complete binary representation of the value.
88 fn to_bytes(&self) -> Vec<u8>;
89}
90
91/// 反序列化 trait,为类型提供从字节数组还原的能力。
92///
93/// Deserialization trait that provides the ability to restore a type from a byte array.
94///
95/// # 返回值说明 / Return Value Notes
96///
97/// `from_bytes` 返回 `Result<(Self, usize), Error>`:
98/// - `Ok((value, bytes_consumed))`:成功时返回还原的值和实际消耗的字节数
99/// - `Err(message)`:失败时返回错误描述
100///
101/// `from_bytes` returns `Result<(Self, usize), Error>`:
102/// - `Ok((value, bytes_consumed))`: On success, returns the restored value and
103/// the number of bytes actually consumed
104/// - `Err(message)`: On failure, returns an error description
105///
106/// # 示例 / Example
107///
108/// ```ignore
109/// use afastdata::AFastDeserialize;
110///
111/// let bytes: Vec<u8> = vec![42, 0, 0, 0];
112/// let (value, consumed) = i32::from_bytes(&bytes).unwrap();
113/// assert_eq!(value, 42);
114/// assert_eq!(consumed, 4);
115/// ```
116pub trait AFastDeserialize: Sized {
117 /// 从字节数组中反序列化一个值。
118 ///
119 /// Deserialize a value from a byte array.
120 ///
121 /// # 参数 / Parameters
122 ///
123 /// - `data`:待反序列化的字节切片,可以是完整数据的子集(从指定偏移量开始)
124 ///
125 /// - `data`: The byte slice to deserialize from. May be a subset of the complete
126 /// data (starting from a specific offset).
127 ///
128 /// # 错误 / Errors
129 ///
130 /// 当字节数据不足或格式无效时返回 `Err`。
131 ///
132 /// Returns `Err` when there are insufficient bytes or the format is invalid.
133 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error>;
134}
135
136/// 从字节切片中精确读取指定数量的字节。内部辅助函数。
137///
138/// Reads exactly `n` bytes from a byte slice at the given offset. Internal helper.
139///
140/// # 参数 / Parameters
141///
142/// - `data`:源字节切片 / Source byte slice
143/// - `offset`:起始偏移量 / Starting offset
144/// - `n`:需要读取的字节数 / Number of bytes to read
145///
146/// # 错误 / Errors
147///
148/// 当 `offset + n` 超出 `data` 长度时返回错误。
149///
150/// Returns an error when `offset + n` exceeds the length of `data`.
151fn read_exact<'a>(data: &'a [u8], offset: usize, n: usize) -> Result<&'a [u8], Error> {
152 if offset + n > data.len() {
153 Err(Error::deserialize(format!(
154 "Not enough bytes: need {} at offset {}, have {}",
155 n,
156 offset,
157 data.len()
158 )))
159 } else {
160 Ok(&data[offset..offset + n])
161 }
162}
163
164// ==================== 整数和浮点类型 / Integer and Float Types ====================
165
166/// 为整数和浮点类型实现序列化/反序列化的宏。
167///
168/// Macro to implement serialization/deserialization for integer and float types.
169///
170/// 每种类型使用其原生字节大小,采用 little-endian 字节序。
171///
172/// Each type uses its native byte size with little-endian byte order.
173macro_rules! impl_serialize_int {
174 ($t:ty, $size:expr) => {
175 impl AFastSerialize for $t {
176 /// 将数值转为 `$size` 字节的 little-endian 字节数组。
177 ///
178 /// Converts the value to a `$size`-byte little-endian byte array.
179 fn to_bytes(&self) -> Vec<u8> {
180 self.to_le_bytes().to_vec()
181 }
182 }
183 impl AFastDeserialize for $t {
184 /// 从字节数组中读取 `$size` 字节并还原为数值。
185 ///
186 /// Reads `$size` bytes from the byte array and restores the value.
187 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
188 let bytes = read_exact(data, 0, $size)?;
189 let arr: [u8; $size] = bytes.try_into().unwrap();
190 Ok((Self::from_le_bytes(arr), $size))
191 }
192 }
193 };
194}
195
196impl_serialize_int!(i8, 1);
197impl_serialize_int!(u8, 1);
198impl_serialize_int!(i16, 2);
199impl_serialize_int!(u16, 2);
200impl_serialize_int!(i32, 4);
201impl_serialize_int!(u32, 4);
202impl_serialize_int!(i64, 8);
203impl_serialize_int!(u64, 8);
204impl_serialize_int!(i128, 16);
205impl_serialize_int!(u128, 16);
206impl_serialize_int!(f32, 4);
207impl_serialize_int!(f64, 8);
208
209// ==================== bool ====================
210
211impl AFastSerialize for bool {
212 /// 将布尔值序列化为 1 个字节:`true` 为 `0x01`,`false` 为 `0x00`。
213 ///
214 /// Serializes the boolean to 1 byte: `true` as `0x01`, `false` as `0x00`.
215 fn to_bytes(&self) -> Vec<u8> {
216 vec![if *self { 1 } else { 0 }]
217 }
218}
219
220impl AFastDeserialize for bool {
221 /// 从 1 个字节反序列化布尔值。仅接受 `0x00`(false)和 `0x01`(true)。
222 ///
223 /// Deserializes a boolean from 1 byte. Only accepts `0x00` (false) and `0x01` (true).
224 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
225 let bytes = read_exact(data, 0, 1)?;
226 match bytes[0] {
227 0 => Ok((false, 1)),
228 1 => Ok((true, 1)),
229 v => Err(Error::deserialize(format!("Invalid bool value: {}", v))),
230 }
231 }
232}
233
234// ==================== 长度前缀辅助函数 / Length Prefix Helpers ====================
235
236/// 将长度值写入缓冲区作为前缀字节。内部辅助函数。
237///
238/// Writes a length value into the buffer as prefix bytes. Internal helper.
239///
240/// 使用 [`LenInt`] 类型编码,little-endian 字节序。
241///
242/// Encoded using the [`LenInt`] type in little-endian byte order.
243fn write_len(buf: &mut Vec<u8>, len: usize) {
244 let v = len as LenInt;
245 buf.extend(v.to_le_bytes());
246}
247
248/// 从字节切片中读取长度前缀。内部辅助函数。
249///
250/// Reads a length prefix from a byte slice. Internal helper.
251///
252/// # 返回值 / Returns
253///
254/// 返回 `(实际长度, 新偏移量)`,其中新偏移量 = 原偏移量 + `LEN_INT_SIZE`。
255///
256/// Returns `(actual_length, new_offset)` where new_offset = original_offset + `LEN_INT_SIZE`.
257fn read_len(data: &[u8], offset: usize) -> Result<(usize, usize), Error> {
258 let bytes = read_exact(data, offset, LEN_INT_SIZE)?;
259 let arr: [u8; LEN_INT_SIZE] = bytes.try_into().unwrap();
260 let len = LenInt::from_le_bytes(arr) as usize;
261 Ok((len, offset + LEN_INT_SIZE))
262}
263
264// ==================== String ====================
265
266impl AFastSerialize for String {
267 /// 将字符串序列化为:`LenInt 长度前缀 + UTF-8 字节`。
268 ///
269 /// Serializes the string as: `LenInt length prefix + UTF-8 bytes`.
270 ///
271 /// 长度前缀表示 UTF-8 字节的长度(不是字符数)。
272 ///
273 /// The length prefix represents the number of UTF-8 bytes (not the character count).
274 fn to_bytes(&self) -> Vec<u8> {
275 let bytes = self.as_bytes();
276 let mut result = Vec::with_capacity(LEN_INT_SIZE + bytes.len());
277 write_len(&mut result, bytes.len());
278 result.extend_from_slice(bytes);
279 result
280 }
281}
282
283impl AFastDeserialize for String {
284 /// 从字节数据中反序列化字符串。
285 ///
286 /// Deserializes a string from byte data.
287 ///
288 /// 先读取 `LenInt` 长度前缀,再读取对应数量的 UTF-8 字节。
289 ///
290 /// First reads the `LenInt` length prefix, then reads the corresponding number
291 /// of UTF-8 bytes.
292 ///
293 /// # 错误 / Errors
294 ///
295 /// 当字节数据不足或包含非法 UTF-8 序列时返回错误。
296 ///
297 /// Returns an error when there are insufficient bytes or the data contains
298 /// invalid UTF-8 sequences.
299 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
300 let (len, offset) = read_len(data, 0)?;
301 let bytes = read_exact(data, offset, len)?;
302 let s = std::str::from_utf8(bytes)
303 .map_err(|e| Error::deserialize(format!("Invalid UTF-8: {}", e)))?;
304 Ok((s.to_owned(), offset + len))
305 }
306}
307
308// ==================== Vec<T> ====================
309
310impl<T: AFastSerialize> AFastSerialize for Vec<T> {
311 /// 将向量序列化为:`LenInt 元素个数前缀 + 逐个元素的序列化数据`。
312 ///
313 /// Serializes the vector as: `LenInt element count prefix + serialized data for each element`.
314 ///
315 /// 每个元素调用其自身的 `to_bytes()` 方法,所有元素的序列化结果依次拼接。
316 ///
317 /// Each element's `to_bytes()` method is called, and all serialized results are
318 /// concatenated sequentially.
319 fn to_bytes(&self) -> Vec<u8> {
320 let mut result = Vec::new();
321 write_len(&mut result, self.len());
322 for item in self {
323 result.extend(item.to_bytes());
324 }
325 result
326 }
327}
328
329impl<T: AFastDeserialize> AFastDeserialize for Vec<T> {
330 /// 从字节数据中反序列化向量。
331 ///
332 /// Deserializes a vector from byte data.
333 ///
334 /// 先读取 `LenInt` 元素个数,再逐个反序列化元素。
335 ///
336 /// First reads the `LenInt` element count, then deserializes each element in order.
337 ///
338 /// # 错误 / Errors
339 ///
340 /// 当字节数据不足或任何元素反序列化失败时返回错误。
341 ///
342 /// Returns an error when there are insufficient bytes or any element fails to
343 /// deserialize.
344 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
345 let (len, mut offset) = read_len(data, 0)?;
346 let mut vec = Vec::with_capacity(len);
347 for _ in 0..len {
348 let (item, new_offset) = T::from_bytes(&data[offset..])?;
349 vec.push(item);
350 offset += new_offset;
351 }
352 Ok((vec, offset))
353 }
354}
355
356// ==================== Option<T> ====================
357
358impl<T: AFastSerialize> AFastSerialize for Option<T> {
359 /// 将 `Option<T>` 序列化。
360 ///
361 /// Serializes an `Option<T>`.
362 ///
363 /// - `None`:写入 `0x00`(1 字节)
364 /// - `Some(value)`:写入 `0x01`(1 字节标记)+ 值的序列化数据
365 ///
366 /// - `None`: Writes `0x00` (1 byte)
367 /// - `Some(value)`: Writes `0x01` (1 byte tag) + the serialized value data
368 fn to_bytes(&self) -> Vec<u8> {
369 match self {
370 Some(val) => {
371 let mut result = vec![1u8];
372 result.extend(val.to_bytes());
373 result
374 }
375 None => vec![0u8],
376 }
377 }
378}
379
380impl<T: AFastDeserialize> AFastDeserialize for Option<T> {
381 /// 从字节数据中反序列化 `Option<T>`。
382 ///
383 /// Deserializes an `Option<T>` from byte data.
384 ///
385 /// 先读取 1 字节标记:`0x00` 表示 `None`,`0x01` 表示 `Some` 并继续读取值。
386 ///
387 /// First reads a 1-byte tag: `0x00` means `None`, `0x01` means `Some` and
388 /// continues to deserialize the value.
389 ///
390 /// # 错误 / Errors
391 ///
392 /// 当标记字节不是 `0x00` 或 `0x01` 时返回错误。
393 ///
394 /// Returns an error when the tag byte is neither `0x00` nor `0x01`.
395 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
396 let bytes = read_exact(data, 0, 1)?;
397 match bytes[0] {
398 0 => Ok((None, 1)),
399 1 => {
400 let (val, new_offset) = T::from_bytes(&data[1..])?;
401 Ok((Some(val), 1 + new_offset))
402 }
403 v => Err(Error::deserialize(format!("Invalid Option tag: {}", v))),
404 }
405 }
406}
407
408// ==================== [T; N] 固定大小数组 / Fixed-size Arrays ====================
409
410impl<T: AFastSerialize, const N: usize> AFastSerialize for [T; N] {
411 /// 将固定大小数组序列化为:逐个元素的序列化数据,无长度前缀。
412 ///
413 /// Serializes a fixed-size array as: element-wise serialized data with no length prefix.
414 ///
415 /// 因为数组大小在编译时已知,所以不需要长度前缀。
416 ///
417 /// Since the array size is known at compile time, no length prefix is needed.
418 fn to_bytes(&self) -> Vec<u8> {
419 let mut result = Vec::new();
420 for item in self {
421 result.extend(item.to_bytes());
422 }
423 result
424 }
425}
426
427impl<T: AFastDeserialize + Default + Copy, const N: usize> AFastDeserialize for [T; N] {
428 /// 从字节数据中反序列化固定大小数组。
429 ///
430 /// Deserializes a fixed-size array from byte data.
431 ///
432 /// 依次反序列化 `N` 个元素,要求元素类型实现 `Default` 和 `Copy`。
433 ///
434 /// Deserializes `N` elements sequentially. Requires the element type to implement
435 /// `Default` and `Copy`.
436 fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
437 let mut arr = [T::default(); N];
438 let mut offset = 0;
439 for item in arr.iter_mut() {
440 let (val, new_offset) = T::from_bytes(&data[offset..])?;
441 *item = val;
442 offset += new_offset;
443 }
444 Ok((arr, offset))
445 }
446}
447
448// ==================== &str (仅序列化 / Serialize Only) ====================
449
450impl AFastSerialize for &str {
451 /// 将字符串切片序列化为:`LenInt 长度前缀 + UTF-8 字节`。
452 ///
453 /// Serializes the string slice as: `LenInt length prefix + UTF-8 bytes`.
454 ///
455 /// 与 `String` 的序列化格式完全一致,方便在不拥有所有权的情况下进行序列化。
456 ///
457 /// Identical to `String` serialization format, allowing serialization without
458 /// taking ownership.
459 fn to_bytes(&self) -> Vec<u8> {
460 let bytes = self.as_bytes();
461 let len = bytes.len() as LenInt;
462 let mut result = len.to_le_bytes().to_vec();
463 result.extend_from_slice(bytes);
464 result
465 }
466}
467
468// ==================== 测试 / Tests ====================
469
470#[cfg(test)]
471mod tests {
472 use super::*;
473
474 /// 通用 round-trip 测试:序列化后再反序列化,验证值和消耗字节数一致。
475 ///
476 /// Generic round-trip test: serialize then deserialize, verifying value and
477 /// consumed byte count are consistent.
478 fn roundtrip<T: AFastSerialize + AFastDeserialize + PartialEq + std::fmt::Debug>(val: &T) {
479 let bytes = val.to_bytes();
480 let (decoded, offset) = T::from_bytes(&bytes).unwrap();
481 assert_eq!(offset, bytes.len());
482 assert_eq!(*val, decoded);
483 }
484
485 #[test]
486 fn test_integers() {
487 roundtrip(&42i8);
488 roundtrip(&255u8);
489 roundtrip(&-1000i16);
490 roundtrip(&60000u16);
491 roundtrip(&-100_000i32);
492 roundtrip(&3_000_000_000u32);
493 roundtrip(&-1_000_000_000_000i64);
494 roundtrip(&18_000_000_000_000_000_000u64);
495 }
496
497 #[test]
498 fn test_floats() {
499 roundtrip(&3.14f32);
500 roundtrip(&2.718281828f64);
501 }
502
503 #[test]
504 fn test_bool() {
505 roundtrip(&true);
506 roundtrip(&false);
507 }
508
509 #[test]
510 fn test_string() {
511 roundtrip(&String::from("hello world"));
512 roundtrip(&String::from(""));
513 roundtrip(&String::from("你好"));
514 }
515
516 #[test]
517 fn test_vec() {
518 roundtrip(&vec![1i32, 2, 3, 4, 5]);
519 roundtrip(&Vec::<i32>::new());
520 roundtrip(&vec![String::from("a"), String::from("b")]);
521 }
522
523 #[test]
524 fn test_option() {
525 roundtrip(&Some(42i32));
526 roundtrip(&None::<i32>);
527 roundtrip(&Some(String::from("hello")));
528 }
529
530 #[test]
531 fn test_array() {
532 roundtrip(&[1i32, 2, 3]);
533 }
534}