Crate context_mapper

source ·
Expand description

Universal library for struct mapping. Provides multiple methods to generate HashMaps with values of any type

§Example problem

Let’s assume that we’ve got this struct

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>
}

Now, we want to get a few info:

  1. avg(&self) -> HashMap<String, f64> returning average amount of money in every field
  2. max(&self) -> HashMap<String, f64> returning max amount of money in every field
  3. info(&self) -> HashMap<String, String> returning general information about fields
  4. detail_info(&self) -> HashMap<String, String>. Similar to 3, but with more info

We would need to implement it manually. It’s cumbersome and inconvinient. That’s where context_mapper becomes a handy tool:

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

§Macros documentation

See ContextMapper for detailed info

§Comparsion to similar libraries

§serde

The main difference between context_mapper and serde is the approach. serde defines single, powerful way of serializing / deserializing structures, enums etc. On the other hand context_mapper does not enforce any standard on the serialization. Its main purpose is to simplify generation of the repetitive struct -> map mappings. Also, it does not support nested structures

§structmap

While being inspiration for this library, structmap is more similar to serde, than context_mapper. Both libraries provide way of converision of the struct to map of strings. However structmap allows users to convert objects from map and then convert them to map. On the other hand it does not allow multiple contexts (multiple maps generation)

Structs§

Traits§

Derive Macros§