#maps #mapper #generate #different #context #mapping #multiple

context-mapper

生成不同映射的单个Rust宏

2 个版本

0.1.1 2024年2月5日
0.1.0 2024年2月4日

964数据结构

MITGPL-3.0-only

10KB
89

上下文映射器

生成不同映射的单个Rust宏

示例

#[derive(ContextMapper)]
#[context_mapper(
    impl(
        context = info::general
        converter = MyConv::to_info,
        type = info::Info,
        fn = general_info
        vis = pub(crate)
    ),
    function(
        context = info::all
        converter = MyConv::to_info,
        type = info::Info,
        fn = all_info
    ),

)]
struct Person {
    name: String,
    address: info::Address,
    age: usize,

    /// Let's hide it for the geneal info, but show for the rest
    #[context_attribute(context(name=info::general, skip))]
    is_a_reptile: bool
}

//

let person = Person {
    //
};

person.general_info();
all_info(&person);

lib.rs:

通用结构映射库。提供多种方法生成任何类型的HashMap值

示例问题

假设我们有一个这样的结构

struct Person {
    name: String
    /// Age in years
    age: usize,
    /// Dept in $ in the certain banks
    dept: BTreeMap<String, f64>,
    /// Amount of money in banks. Accounts in $
    bank_account: BTreeMap<String, f64>,
    /// Amount of money in the wallet in $
    wallet: f64,
    /// Amount of money in the crypto in crypto-wallets. Transformed to $
    crypto: BTreeMap<String, f64>
}

现在,我们想要获取一些信息

  1. avg(&self) -> HashMap<String, f64> 返回每个字段的平均金额
  2. max(&self) -> HashMap<String, f64> 返回每个字段的最大金额
  3. info(&self) -> HashMap<String, String> 返回有关字段的通用信息
  4. detail_info(&self) -> HashMap<String, String> 与第3个类似,但包含更多信息

我们需要手动实现它。这很麻烦,不方便。这就是context_mapper成为实用工具的地方

#[derive(ContextMapper)]
// F64 traits
#[context_mapper(
    trait(
        context = p01::average,
        type = f64,
        converter = MyAvgTrait::avg,
        generic(
            name = Averager,
            method_name = avg
        )
    ),
    trait(
        context = p02::max,
        type = f64,
        converter = MyMaxTrait::max,
        simple(
            name = Maximizer,
            method_name = max
        )
    )
)]
// String traits
#[context_mapper(
    trait(
        context = p03::general,
        type = String,
        converter = std::string::ToString::to_string,
        generic(
            path = GenInfo,
            method_name = info
        )
    ),
    trait(
        context = p04::max,
        type = f64,
        converter = generic_info,
        simple(
            path = my::DetailedInfo,
            method_name = info
        )
    )
)]
struct Person {
    #[context_attribute(context(name=p01::average, skip))]
    #[context_attribute(context(name=p02::max, skip))]
    name: String

    /// Age in years
    #[context_attribute(context(name=p01::average, skip))]
    #[context_attribute(context(name=p02::max, skip))]
    age: usize,

    /// Dept in $ in the certain banks
    #[context_attribute(
        context(name=p02::max, converter=punishment::with_interests)
    )]
    dept: BTreeMap<String, f64>,

    /// Amount of money in banks. Accounts in $
    bank_account: BTreeMap<String, f64>,
    /// Amount of money in the wallet in $
    wallet: f64,
    /// Amount of money in the crypto in crypto-wallets. Transformed to $
    crypto: BTreeMap<String, f64>
}

宏文档

有关详细信息,请参阅 ContextMapper

与其他库的比较

serde

context_mapper 相比,serde 的主要区别在于方法。 serde 定义了一种单一且强大的序列化/反序列化结构、枚举等的方法。另一方面,context_mapper 不强制执行任何序列化的标准。其主要目的是简化重复的 struct -> map 映射的生成。此外,它不支持嵌套结构。

structmap

虽然该库受到了 structmap 的启发,但它与 context_mapper 更相似于 serde。这两个库都提供了将结构体转换为字符串映射的方法。然而,structmap 允许用户从映射中转换对象,然后再将它们转换为映射。另一方面,它不允许多个上下文(多个映射生成)。

依赖

~0.7–1.1MB
~21K SLoC