1

我有一个需要包含“字节”字段的结构,我正在尝试从 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(即 as Vec<u8>)时我遇到了同样的问题

编辑解决方案:

正如@lpiepiora 在下面指出的那样,这需要一个额外的包装器。类似于以下内容,由serde_bytescrate 提供:

#[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)
    }
}
4

1 回答 1

2

假设您正在尝试将 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> 需要一个数组

于 2021-04-30T21:51:26.753 回答