问题描述
我有一个需要包含“字节”字段的结构,我正在尝试从 JSON 中反序列化它。
当我使用 &'a [u8]
时,这有效,但随后我需要向该结构以及包含它的结构添加生命周期注释,依此类推。
我以为我可以通过“拥有”字节并使用封闭的 Box
来解决这个问题,但这不起作用。我正在尝试弄清楚为什么不,或者是否有办法(使用一些 serde 注释,或该字段的自定义帮助程序,或其他方法)使其工作。
更具体地说,这是有效的:
struct Foo<'a> {
some_field: Option<String>,field_of_interest: &'a [u8],}
这不会:
struct Foo {
some_field: Option<String>,field_of_interest: Box<[u8]>,}
在这两种情况下,我都将其称为:
let my_foo: Foo = serde_json::from_slice(...);
我在将 Box
替换为 Vec
(即 Vec<u8>
)时遇到了同样的问题
使用解决方案进行编辑:
正如@lpiepiora 在下面指出的,这需要一个额外的包装器。类似于以下内容,由 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)
}
}
解决方法
假设您尝试将 JSON 字符串反序列化为 Vec<u8>
,您可以添加一个 crate serde_bytes。
例如:
use serde::Deserialize;
#[derive(Deserialize,Debug)]
struct Foo {
a: Option<String>,#[serde(with = "serde_bytes")]
b: Vec<u8>
}
fn main() {
let x = b"{ \"a\": \"a-value\",\"b\": \"aaaaaaaa\" }";
let my_foo: Foo = serde_json::from_slice(x).unwrap();
println!("{:?}",my_foo);
}
将打印:Foo { a: Some("a-value"),b: [97,97,97] }
。
通常Vec<u8>
expects an array。