如何将 JSON 反序列化为具有 Box<[u8]> 值的结构?

How to deserialize JSON into a structure with a Box<[u8]> value?

我有一个需要包含“字节”字段的结构,我正在尝试从 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(...);

我在用 Vec 替换 Box 时遇到了同样的问题(即 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, 97, 97, 97, 97, 97] }.

正常 Vec<u8> expects an array.