#single #serde #vec #multiple-values

no-std serde_single_or_vec

可以从序列或单个值反序列化的类型

2 个稳定版本

1.0.1 2020年11月16日
1.0.0 2020年11月13日

#854 in 数据结构

MIT/Apache

23KB
442

serde_single_or_vec

此crate提供了SingleOrVec类型,允许使用serde解析单个类型T或类型T的向量。当服务器返回一个数组(如果有多个值)或一个值(如果只有一个值)时,需要这个功能。

示例


#[derive(Deserialize, Serialize)]
struct Response {
    single: SingleOrVec<'static, u8>,
    multiple: SingleOrVec<'static, u8>,
}

let json = r#"{
  "single": 0,
  "multiple": [
    0,
    1,
    2
  ]
}"#;
let res: Response = serde_json::from_str(json).unwrap();
assert_eq!(json, &serde_json::to_string_pretty(&res).unwrap());

格式

默认情况下,SingleOrVec类型将内容反序列化为单个值或数组(如果包含多个值)。要更改此行为,可以定义输出格式。


#[derive(Deserialize, Serialize)]
struct Response {
    single: SingleOrVec<'static, u8>,
    multiple: SingleOrVec<'static, u8>,
}

let json = "[0]";

let res: SingleOrVec<'_, u8, PreferSingle> = serde_json::from_str(json).unwrap();
assert_eq!("0", &serde_json::to_string(&res).unwrap());

let res: SingleOrVec<'_, u8, AlwaysVector> = serde_json::from_str(json).unwrap();
assert_eq!("[0]", &serde_json::to_string(&res).unwrap());

存储后端

默认后端是Vec<T>,因此总是导致分配。另一种选择是使用Cow<'_, T>作为后端,这只需要为单个值分配。

请注意,这仅在序列化此值时有效,由于serde#1852,反序列化始终分配。

let json = "[0,1,2]";
let res: SingleOrVec<'_, u8, PreferSingle, Cow<'_, [u8]>> = serde_json::from_str(json).unwrap();
assert_eq!(json, &serde_json::to_string(&res).unwrap());

自定义存储类型

还可以通过使用Storage特质实现自定义存储后端。

use arrayvec::ArrayVec;

struct ArrayVecStorage {}

impl<T> Storage<'_, T> for ArrayVecStorage {
    type Backing = ArrayVec<[T; 4]>;

    fn single(ty: T) -> Self::Backing {
        let mut vec = ArrayVec::new();
        vec.push(ty);
        vec
    }

    fn get_first_with_len(b: &Self::Backing) -> Option<(&T, usize)> {
        b.split_first().map(|(t, r)| (t, r.len()))
    }
}

let json = "[0,1,2]";
let res: SingleOrVec<'_, u8, PreferSingle, ArrayVecStorage> = serde_json::from_str(json).unwrap();
assert_eq!(json, &serde_json::to_string(&res).unwrap());

let json = "0";
let res: SingleOrVec<'_, u8, PreferSingle, ArrayVecStorage> = serde_json::from_str(json).unwrap();
assert_eq!(json, &serde_json::to_string(&res).unwrap());

no_std

可以使用no_std使用此crate,但是,与serde一样,需要stdalloc

许可

根据您的选择,许可为以下之一

贡献

除非您明确声明,否则根据Apache-2.0许可证定义的,任何有意提交以包含在作品中的贡献,都应根据上述方式双许可,不附加任何额外条款或条件。

许可:MIT OR Apache-2.0

依赖

~0.4–1MB
~22K SLoC