1个稳定版本
1.0.0 | 2023年11月6日 |
---|
#22 in #fixed-length
9KB
77 代码行
fixed-size
fixed-size
- 一个结构体属性,用于设置某些通常是动态的字段的固定大小
lib.rs
:
结构体属性,用于设置某些通常是动态的字段的固定大小
这在生成由prost创建的结构体时很有用,并且这些结构体需要与固定长度字符串的serde格式一起使用
示例
syntax = "proto3";
message Foo
{
string my_string = 1;
}
Prost将为my_string字段创建使用String
。如果您有一个需要字符串恰好为4个字符的二进制格式,这将难以以通用方式处理。如果您添加了#[fixed(my_string=4)]
属性,那么您将得到一个ArrayString::<4>
。
默认情况下,将使用ArrayString,但可以使用#[fixed(typ=MyString, thestring=4)]
来覆盖。典型的用法是
use arrayvec::ArrayString;
struct MyString<const CAP: usize>(ArrayString<CAP>);
impl<const CAP: usize> AsRef<ArrayString<CAP>> for MyString<CAP> {
fn as_ref(&self) -> &ArrayString<CAP> {
&self.0
}
}
impl<const CAP: usize> serde::Serialize for MyString<CAP> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where S: serde::Serializer
{
// specialized serialize to override ArrayString's conversion to &str
todo!()
}
}
// More impls, probably AsMut, etc.
use arrayvec::ArrayString;
use fixed_size::fixed;
#[fixed(my_string=4)]
#[derive(serde::Serialize, serde::Deserialize, PartialEq, Debug)]
struct Foo {
my_string: String,
}
let foo = Foo { my_string: ArrayString::<4>::from("abcd").unwrap() };
// bincode actually supports var length strings but it's just used as an example and test
let encoded = bincode::serialize(&foo).unwrap();
let decoded: Foo = bincode::deserialize(&encoded[..]).unwrap();
assert_eq!(foo, decoded);
向my_string添加少于4个字符将用0填充值。添加多于4个字符将导致错误。
依赖项
~0.4–0.9MB
~20K SLoC