Skip to main content

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