#json-array #deserialize #serde #no-std #format

无std serde-map-to-array

辅助工具,支持将映射转换为人类可读编码格式的命名键值对序列

3 个稳定版本

1.1.1 2023年7月28日
1.1.0 2023年7月4日
1.0.0 2023年7月2日

#615编码

Download history 2904/week @ 2024-04-20 2152/week @ 2024-04-27 2066/week @ 2024-05-04 2039/week @ 2024-05-11 2460/week @ 2024-05-18 2663/week @ 2024-05-25 1644/week @ 2024-06-01 2271/week @ 2024-06-08 2808/week @ 2024-06-15 2536/week @ 2024-06-22 2513/week @ 2024-06-29 3320/week @ 2024-07-06 3036/week @ 2024-07-13 2831/week @ 2024-07-20 773/week @ 2024-07-27 1139/week @ 2024-08-03

每月8,270次下载

MIT/Apache

56KB
1K SLoC

serde-map-to-array   ci_badge crates_io_badge docs_badge msrv_badge


这个crate提供了非官方的serde辅助工具,以支持将映射转换为人类可读的编码格式的命名键值对序列。

这允许在可变映射面前保持稳定的模式。

例如,假设我们有一个包含值 [(1, "one"), (2, "two"), (3, "three")] 的映射。将其编码为JSON,结果是

{"1":"one","2":"two","3":"three"}

尽管如此,我们无法为这个JSON对象指定一个模式,除非映射的内容始终包含在键 123 下的三个条目。

这个crate允许将这样的映射编码为JSON数组对象,每个对象恰好包含两个具有静态名称的元素

[{"key":1,"value":"one"},{"key":2,"value":"two"},{"key":3,"value":"three"}]

对于可以生成模式的情况。

此外,这避免了将映射的键类型编码为字符串。

默认情况下,键值对将使用“key”和“value”作为标签,但可以通过实现KeyValueLabels的struct来提供自己的标签进行修改。

注意,对于二进制(非人类可读)编码格式,默认的序列化和反序列化被保留。

no_std

默认情况下,该crate是no_std,但使用alloc。在这种情况下,提供了对BTreeMap和类似类型的支持。

如果启用了功能std,则还提供了对HashMap和类似类型的支持,但禁用了no_std支持。

示例

使用默认字段值“key”和“value”

use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
use serde_map_to_array::BTreeMapToArray;

#[derive(Default, Serialize, Deserialize)]
struct Data {
    #[serde(with = "BTreeMapToArray::<u64, String>")]
    inner: BTreeMap<u64, String>,
}

let mut data = Data::default();
data.inner.insert(1, "one".to_string());
data.inner.insert(2, "two".to_string());

assert_eq!(
    serde_json::to_string(&data).unwrap(),
    r#"{"inner":[{"key":1,"value":"one"},{"key":2,"value":"two"}]}"#
);

使用非默认字段标签

use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_map_to_array::{KeyValueLabels, HashMapToArray};

struct MyKeyValueLabels;

impl KeyValueLabels for MyKeyValueLabels {
    const KEY: &'static str = "id";
    const VALUE: &'static str = "name";
}

#[derive(Default, Serialize, Deserialize)]
struct Data {
    #[serde(with = "HashMapToArray::<u64, String, MyKeyValueLabels>")]
    inner: HashMap<u64, String>,
}

let mut data = Data::default();
data.inner.insert(1, "one".to_string());
data.inner.insert(2, "two".to_string());
// The hashmap orders the entries randomly.
let expected_json = if *data.inner.keys().next().unwrap() == 1 {
    r#"{"inner":[{"id":1,"name":"one"},{"id":2,"name":"two"}]}"#
} else {
    r#"{"inner":[{"id":2,"name":"two"},{"id":1,"name":"one"}]}"#
};

assert_eq!(serde_json::to_string(&data).unwrap(), expected_json);

使用自定义的BTreeMap类似类型

use std::collections::{btree_map, BTreeMap};
use serde::{Deserialize, Serialize};
use serde_map_to_array::{BTreeMapToArray, DefaultLabels};

#[derive(Serialize, Deserialize)]
struct MyMap(BTreeMap<u64, String>);

/// We need to implement `IntoIterator` to allow serialization.
impl<'a> IntoIterator for &'a MyMap {
    type Item = (&'a u64, &'a String);
    type IntoIter = btree_map::Iter<'a, u64, String>;
    fn into_iter(self) -> Self::IntoIter {
        self.0.iter()
    }
}

/// We need to implement `From<BTreeMap>` to allow deserialization.
impl From<BTreeMap<u64, String>> for MyMap {
    fn from(map: BTreeMap<u64, String>) -> Self {
        MyMap(map)
    }
}

#[derive(Serialize, Deserialize)]
struct Data {
    #[serde(with = "BTreeMapToArray::<u64, String, DefaultLabels, MyMap>")]
    inner: MyMap,
}

使用具有非标准哈希器的HashMap

use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use hash_hasher::HashBuildHasher;
use serde_map_to_array::{DefaultLabels, HashMapToArray};

#[derive(Serialize, Deserialize)]
struct Data {
    #[serde(with = "HashMapToArray::<u64, String, DefaultLabels, HashBuildHasher>")]
    inner: HashMap<u64, String, HashBuildHasher>,
}

使用自定义的HashMap类似类型

use std::collections::{hash_map::{self, RandomState}, HashMap};
use serde::{Deserialize, Serialize};
use serde_map_to_array::{DefaultLabels, HashMapToArray};

#[derive(Serialize, Deserialize)]
struct MyMap(HashMap<u64, String>);

/// We need to implement `IntoIterator` to allow serialization.
impl<'a> IntoIterator for &'a MyMap {
    type Item = (&'a u64, &'a String);
    type IntoIter = hash_map::Iter<'a, u64, String>;
    fn into_iter(self) -> Self::IntoIter {
        self.0.iter()
    }
}

/// We need to implement `From<HashMap>` to allow deserialization.
impl From<HashMap<u64, String>> for MyMap {
    fn from(map: HashMap<u64, String>) -> Self {
        MyMap(map)
    }
}

#[derive(Serialize, Deserialize)]
struct Data {
    #[serde(with = "HashMapToArray::<u64, String, DefaultLabels, RandomState, MyMap>")]
    inner: MyMap,
}

JSON Schema 支持

可以通过设置功能json-schema来启用通过schemars生成JSON模式的支持。

默认情况下,KeyValue struct的模式名称将被设置为"KeyValue_for_{K::schema_name()}_and_{V::schema_name()}",并且struct及其键和值字段将没有描述(通常从struct及其字段的文档注释中生成)。这些都可以通过实现KeyValueJsonSchema的struct来提供自己的值进行修改。

许可证

serde-map-to-array在MIT许可证和Apache许可证(版本2.0)的条款下分发。

有关详细信息,请参阅LICENSE-MITLICENSE-APACHE

依赖关系

~110–510KB
~11K SLoC