2个稳定版本
1.1.0 | 2023年8月8日 |
---|---|
1.0.0 | 2023年4月6日 |
#1699 在 编码
920 每月下载次数
在 6 个crate中(2个直接)使用
38KB
754 行
compact-encoding
Rust中构建小型且快速的解析器和序列化器的一系列紧凑编码方案。与原始JavaScript紧凑编码库二进制兼容。
许可证
lib.rs
:
构建小型且快速的解析器和序列化器的一系列紧凑编码方案
与原始JavaScript紧凑编码库二进制兼容。
使用方法
基本
仅使用此处实现的类型(使用[EncodingError]的正确处理替换unwrap()
)
use compact_encoding::{CompactEncoding, State};
// Start with an empty state
let mut enc_state = State::new();
let number = 41_u32;
let str = "hi".to_string();
// Use preencode to figure out how big a buffer is needed
enc_state.preencode(&number).unwrap();
enc_state.preencode(&str).unwrap();
// Create buffer of pre-encoded size
let mut buffer = enc_state.create_buffer();
assert_eq!(buffer.len(), 1 + 1 + 2);
// Then actually encode the values
enc_state.encode(&number, &mut buffer).unwrap();
enc_state.encode(&str, &mut buffer).unwrap();
assert_eq!(buffer.to_vec(), vec![41_u8, 2_u8, b'h', b'i']);
// On the decoding end, create a state from byte buffer
let mut dec_state = State::from_buffer(&buffer);
let number_dec: u32 = dec_state.decode(&buffer).unwrap();
let str_dec: String = dec_state.decode(&buffer).unwrap();
assert_eq!(number_dec, number);
assert_eq!(str_dec, str);
自定义
如果您想直接编码自己的结构体,可以通过自己实现[CompactEncoding]来实现(使用[EncodingError]的正确处理替换unwrap()
)
use compact_encoding::{CompactEncoding, EncodingError, State};
#[derive(Debug, PartialEq)]
struct MyStruct {
my_flag_1: bool,
my_flag_2: bool,
my_values: Vec<[u8; 32]>,
}
impl CompactEncoding<MyStruct> for State {
fn preencode(&mut self, value: &MyStruct) -> Result<usize, EncodingError> {
self.add_end(1)?; // flags
if !value.my_values.is_empty() {
self.preencode(&value.my_values)?;
}
Ok(self.end())
}
fn encode(&mut self, value: &MyStruct, buffer: &mut [u8]) -> Result<usize, EncodingError> {
let mut flags: u8 = 0;
if value.my_flag_1 {
flags |= 1;
}
if value.my_flag_2 {
flags |= 2;
}
if !value.my_values.is_empty() {
flags |= 4;
}
self.encode(&flags, buffer)?;
if !value.my_values.is_empty() {
self.encode(&value.my_values, buffer)?;
}
Ok(self.start())
}
fn decode(&mut self, buffer: &[u8]) -> Result<MyStruct, EncodingError> {
let flags: u8 = self.decode(buffer)?;
let my_flag_1: bool = flags & 1 != 0;
let my_flag_2: bool = flags & 2 != 0;
let my_values: Vec<[u8; 32]> = if flags & 4 != 0 {
self.decode(buffer)?
} else {
vec![]
};
Ok(MyStruct {
my_flag_1,
my_flag_2,
my_values
})
}
}
// Test values
let empty = MyStruct {
my_flag_1: false,
my_flag_2: true,
my_values: vec![]
};
let non_empty = MyStruct {
my_flag_1: true,
my_flag_2: false,
my_values: vec![[1; 32], [2; 32]]
};
// Start with an empty state
let mut enc_state = State::new();
enc_state.preencode(&empty).unwrap();
enc_state.preencode(&non_empty).unwrap();
let mut buffer = enc_state.create_buffer();
// With the above use of a flags byte, the empty value encodes to only one byte
assert_eq!(buffer.len(), 1 + 1 + 1 + 2 * 32);
// Then actually encode the values
enc_state.encode(&empty, &mut buffer).unwrap();
enc_state.encode(&non_empty, &mut buffer).unwrap();
// On the decoding end, create a state from byte buffer
let mut dec_state = State::from_buffer(&buffer);
// And decode directly to your own struct
let empty_dec: MyStruct = dec_state.decode(&buffer).unwrap();
let non_empty_dec: MyStruct = dec_state.decode(&buffer).unwrap();
assert_eq!(empty_dec, empty);
assert_eq!(non_empty_dec, non_empty);
注意:这仅在您不将结构体导出至crate之外时有效。如果导出结构体,孤儿规则将要求您为[State]实现包装器,例如 struct MyState(State);
并为包装器结构体实现[CompactEncoding]。