bytes
bytes copied to clipboard
How to handle Vec<Vec<u8>>
Hi, i have a message to send in the form of:
type PubKey = Vec<u8>;
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag="kind")]
pub enum Envelope<T> {
Greeting {
#[serde(with="serde_bytes")]
id: PubKey,
#[serde(with="serde_bytes")]
shared: PubKey,
thin: bool
},
AllKnown {
all_known: Vec<PubKey>
},
}
As you can see, PubKey
is only a Vec<u8>
, what is the most idiomatic way to pack this. I do not want to put the Vec<u8>
in a struct to use serde_bytes
.
Is there something i am missing?
It would be really neat to annotated all_known
just with #[serde(with="serde_bytes")]
.
It seems a pretty common problem to be to have an array of byte arrays.
serde_bytes
only supports a few types and cannot support arbitrary data structures. You can use the serde_with::Bytes
type, which is more powerful than what serde_bytes
offers and can be used with more collections. The crate documentation shows how you can use it in nested situations.
#[serde_with::serde_as]
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag="kind")]
pub enum Envelope<T> {
AllKnown {
#[serde_as(as = "Vec<serde_with::Bytes>")]
all_known: Vec<PubKey>
},
}
If you want to use serde_bytes
, you will either need to write the deserialization logic for Vec<PubKey>
yourself, for example by deserializing into a Vec<ByteBuf>
and turning that into a Vec<PubKey>
, or aliasing PubKey
to ByteBuf
, which already has the serialization behavior you want.
Something like this should work:
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<PubKey>, D::Error>
where
D: Deserializer,
{
let tmp: Vec<serde_bytes::ByteBuf> = Vec::deserialize(deserializer)?;
Ok(tmp.into_iter().map(|x| x.into_vec()).collect())
}