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}