MCPcopy Index your code
hub / github.com/ex0dus-0x/structmap

github.com/ex0dus-0x/structmap @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
21 symbols 23 edges 4 files 2 documented · 10%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

structmap

Actions crates.io version Docs

Procedural macro crate for converting between Rust struct types and associative containers.

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();

This removes the need to pattern match on attributes and keys when making a conversion.

This was largely inspired by previous work done by @Ameobea, but extends on it much further to support conversion both ways, generic value types, and Rust 2018 conventions.

Usage

In your Cargo.toml file, include the crate as so:

[dependencies]
structmap = "0.1"
structmap-derive = "0.1"

Now let's demonstrate conversion! Note that your struct type should extend the Default trait for type conversion to account for uninitialized attributes.

structmap supports conversion between two types of map aliases:

  1. StringMap - Strings for both keys and values. Conversion is supported only one-way at the moment from struct to BTreeMap, but not the other way around.
  2. GenericMap - Generic serde-style Values as values. Conversion is supported both ways, but limited.

Map to Struct

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

Struct to Map

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");
}

Need a different key name when converting from a struct to a map container? Use #[rename] for struct attributes!

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

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

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

Contributions

All complex types, include dynamic arrays, Options, Results and data structures are not yet supported (which you can help implement!).

Feel free to let me know if there are any outstanding features that should be implemented!

Big thanks to the following contributors:

License

MIT License

Extension points exported contracts — how you extend this code

FromMap (Interface)
(no doc)
src/lib.rs
ToMap (Interface)
(no doc)
src/lib.rs

Core symbols most depended-on inside this repo

parse_rename_attrs
called by 1
structmap-derive/src/lib.rs
new
called by 0
src/value.rs
bool
called by 0
src/value.rs
i64
called by 0
src/value.rs
u64
called by 0
src/value.rs
f64
called by 0
src/value.rs
String
called by 0
src/value.rs
from_map
called by 0
structmap-derive/src/lib.rs

Shape

Function 8
Method 7
Class 2
Enum 2
Interface 2

Languages

Rust100%

Modules by API surface

tests/test.rs8 symbols
src/value.rs8 symbols
structmap-derive/src/lib.rs3 symbols
src/lib.rs2 symbols

For agents

$ claude mcp add structmap \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact