#attributes #fixed-length #macro #string #size #struct #variables

macro fixed-size

属性宏,用于在结构体定义中将可变长度类型替换为固定长度类型。当使用prost时,可以用来覆盖String。

1个稳定版本

1.0.0 2023年11月6日

#22 in #fixed-length

MIT/Apache

9KB
77 代码行

crates.io MIT/Apache 2.0

fixed-size

fixed-size - 一个结构体属性,用于设置某些通常是动态的字段的固定大小

在docs.rs上的文档


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