#container #associative #proc-macro #struct #procedural #converting #conversion

struct2map

用于在Rust结构体和关联容器之间进行转换的宏库

1 个不稳定版本

0.1.6 2022年10月11日

#2625Rust模式

MIT 协议

10KB
102

structmap

Actions crates.io version Docs

用于在Rust的struct类型和关联容器之间进行转换的宏包。

use std::collections::BTreeMap;
// converting between a struct like ...
struct SomeData {
    key: String
}

// ... and a BTreeMap like ...
let somedata_hm: BTreeMap<String, String> = BTreeMap::new();

这消除了在转换时需要模式匹配属性和键的需求。

这主要受到之前的工作的启发,由@Ameobea完成,但它在此基础上扩展得更多,支持双向转换、泛型值类型和Rust 2018约定。

用法

在您的 Cargo.toml 文件中,按照以下方式包含包

[dependencies]
structmap = "0.1"

现在让我们演示转换!请注意,您的 struct 类型应扩展 Default 特性以进行类型转换,以处理未初始化的属性。

structmap 支持两种类型的映射别名之间的转换

  1. StringMap - 键和值都是字符串。目前仅支持从结构体到BTreeMap的单向转换,但不能反向转换。
  2. GenericMap - 作为值的泛型 serde-style Value。支持双向转换,但有限。

映射到结构体

use structmap::FromMap;
use structmap_derive::FromMap;

#[derive(FromMap)]
struct TestStruct {
    name: String,
    value: i64,
}

impl Default for TestStruct {
    fn default() -> Self {
        Self {
            name: String::new(),
            value: 0
        }
    }
}

fn main() {
	// create a hashmap with key-value pairs
    let mut hm = GenericMap::new();

    // `Value` is an enum wrapper to support genericized types, to support structs
    // with varying types for their fields.
    hm.insert(String::from("name"), Value::new(String::from("example")));
    hm.insert(String::from("value"), Value::new(0_i64));

    // convert hashmap to struct, and check attributes
    let test: TestStruct = TestStruct::from_genericmap(hm);
    assert!(test.name == "example");
    assert!(test.value == 0);
}

结构体到映射

use structmap::{ToMap, value::Value};
use structmap_derive::ToMap;
use std::collections::BTreeMap;

#[derive(ToMap, Default)]
struct TestStruct {
    name: String,
    value: i64,
}

// impl Default ...

fn main() {
    let test_struct = TestStruct {
        name: String::from("example"),
        value: 0,
    };

    // convert struct to generic map, and check attributes
    let hm: BTreeMap<String, Value> = TestStruct::to_genericmap(test_struct);
    assert!(hm.get("name").unwrap().string().unwrap() == "example");
    assert!(hm.get("value").unwrap().i64().unwrap() == 0);

    let test_struct = TestStruct {
        name: String::from("example"),
        value: 0,
    };

    // convert struct to string map, and check attributes
    let hm: BTreeMap<String, String> = TestStruct::to_stringmap(test_struct);
    assert!(hm.get("name").unwrap() == "example");
    assert!(hm.get("value").unwrap() == "0");
}

在将结构体转换为映射容器时需要不同的键名?使用 #[rename] 为结构体属性命名!

use structmap::ToMap;
use structmap_derive::ToMap;

#[derive(ToMap, Default)]
struct TestStruct {
    #[rename(name = "Full Name")]
    name: String,

    #[rename(name = "Data")]
    value: String,
}

贡献

尚未支持所有复杂类型,包括动态数组、OptionResult 和数据结构(您可以帮忙实现!)。

如果您有任何应该实现的功能,请随时告诉我!

许可证

MIT许可证

依赖关系

~1.5MB
~35K SLoC