I have a struct that needs to include a "bytes" field, and I'm trying to deserialize it from JSON.
When I use &'a [u8]
, this works, but then I need to add a lifetime annotation to this struct, and the struct that encloses it, and so on.
I thought I'd get around it by having the bytes "owned" and use an enclosing Box
, but that didn't work. I'm trying to figure out why not, or whether there's a way (either with some serde annotations, or a custom helper for this field, or something else) to get this to work.
More concretely, this works:
struct Foo<'a> {
some_field: Option<String>,
field_of_interest: &'a [u8],
}
And this does not:
struct Foo {
some_field: Option<String>,
field_of_interest: Box<[u8]>,
}
In both cases, I'm calling it as:
let my_foo: Foo = serde_json::from_slice(...);
I encountered the same issue when replacing Box
with Vec
(i.e. as Vec<u8>
)
Edit with solution:
As @lpiepiora pointed out below, this needs an additional wrapper. Something like the following, which is provided by the serde_bytes
crate:
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for Box<[u8]> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice)
}
}
Assuming, that you're trying to deserialize JSON string to
Vec<u8>
, you can add a crate serde_bytes.For example:
Would print:
Foo { a: Some("a-value"), b: [97, 97, 97, 97, 97, 97, 97, 97] }
.Normally
Vec<u8>
expects an array.