#byte #byte-size #serialization #traits #chain #iterator

tobytes

一个小型库,用于简化类型到字节编码

1个不稳定版本

0.1.0 2020年12月7日

#2245 in 编码

Download history 25/week @ 2024-03-14 47/week @ 2024-03-21 122/week @ 2024-03-28 20/week @ 2024-04-04 12/week @ 2024-04-25 69/week @ 2024-05-02 2/week @ 2024-05-23 30/week @ 2024-05-30 65/week @ 2024-06-06 10/week @ 2024-06-13 4/week @ 2024-06-20

101 次每月下载

自定义许可

15KB
140

本库的主要目标是简化类型和结构到字节的序列化。

为什么?

如果经常与二进制格式/协议打交道,则需要在实现解码和编码类型和结构以便进一步处理包含的数据上花费大量时间。

对于解码,解析生成器如 nom 非常有用且易于实现。这个库试图通过引入两个新的特质来提供一个轻量级的编码/输出组合器,从而可以使用迭代器功能创建所需的字节输出链。

为什么需要这样的特质

  1. 通过引入这样的特质,在许多情况下,可以通过编码和按顺序链接子项来实施复杂(复合)结构。

  2. 类型字段仍然可以用于编码,但它们对顺序或实际大小没有硬依赖

    例如:具有2字节(u16)编码大小的协议字段仍然可以表示为结构/类型中的 usize,从而节省了大量转换和类型转换。

  3. 不需要类型提供特定数量的内存以进行序列化(类型或类型的序列化可以是100%计算性的)

    例如:假设这个协议类型/结构(数据包)

    +-----------------+-------------------+-----------------+
    | field1 (1 Byte) | reserved (7 Byte) | filed2 (8 Byte) |
    +-----------------+-------------------+-----------------+
    

    内部可以表示和实现如下

    use tobytes::ByteView;
    use tobytes::ToBytes;
    
    struct Packet {
    field1: u8,
    field2: u64
    }
    
    impl Packet {
       const RESERVED : u8 = 0x00;
    }
    
    impl ByteView for Packet {
    
    
        fn byte_at(&self, index: usize) -> Option<u8> {
            if index < ByteView::byte_size(self) {
                match index {
                    0 => self.field1.byte_at(index),
                    1..=7 => Some(Packet::RESERVED),
                    8..=15 => self.field2.byte_at(index -7),
                    _ => None
                }       
            }           
            else {
               None
            }   
        }
    
        fn byte_size(&self) -> usize {
        ByteView::byte_size(&self.field1) + 7usize + ByteView::byte_size(&self.field2)
        }
    }
    
    let field1 = 0xaau8;
    let field2 = 0xaabbccddeeff11u64.to_be();
    let p = Packet {field1, field2};
    let mut bytes = p.to_bytes();
    
    assert_eq!(16usize, p.byte_size());
    
    assert_eq!(
        vec![0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11],
        bytes.collect::<Vec<u8>>()
    );
    

如何使用?(用法)

示例

如何序列化不同端序和大小的整数

use tobytes::ByteView;
use tobytes::ToBytes;

let uint16_be : u16 = 0x0A0Bu16.to_be();
let uint16_le : u16 = 0x0C0Du16.to_le();
let uint32_le : u32 = 0x01020304u32.to_le();

let uint16_be_bytes = uint16_be.to_bytes();
let uint16_le_bytes = uint16_le.to_bytes();
let uint32_le_bytes = uint32_le.to_bytes();

let mut bytes = uint16_be_bytes.chain(uint16_le_bytes.chain(uint32_le_bytes));

assert_eq!(vec![0x0A, 0x0B, 0x0D, 0x0C, 0x04, 0x03, 0x02, 0x01], bytes.collect::<Vec<u8>>())

如何序列化包含不同端序和类型的自定义类型

TBD

如何序列化包含实现ByteView特质的类型的自定义类型

TBD

待办事项

  • 为内置整数和浮点类型实现ByteView
  • 为类似于切片的类型实现ByteView
  • 为ByteView实现derive宏

没有运行时依赖