Crate fixed_size
source ·Expand description
struct attribute to set fixed sizes for certain fields which are normally dynamic
This is useful when generating structs from protobufs using prost and also using those structs with a serde format that requires fixed length strings
Example
syntax = "proto3";
message Foo
{
string my_string = 1;
}
Prost will create use String
for the my_string field. If you have a binary format requiring
exactly 4 characters in a string this will be difficult to handle in a generic manner. If you add
the #[fixed(my_string=4)]
attribute then you’ll end up with a ArrayString::<4>
instead.
By default, ArrayString will be used but this can be overridden with #[fixed(typ=MyString, thestring=4)]
The typical use is
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);
Adding fewer than 4 characters to my_string will 0 pad the value. Adding more than 4 characters will result in an error.
Attribute Macros
- Replace one or more variable length fields with a fixed length equivalent