3 releases (breaking)
new 0.3.0 | Mar 1, 2025 |
---|---|
0.2.0 | Feb 27, 2025 |
0.1.0 | Feb 27, 2025 |
#1719 in Rust patterns
404 downloads per month
16KB
107 lines
DoLess - Procedural Macro for Struct Mapping 🦀
DoLess
is a Rust procedural macro that allows structs to be initialized from a HashMap<String, String>
. It automatically maps field values, providing type-safe conversions.
🚀 Features
- 🏢 Auto-implements
From<HashMap<String, String>>
for structs. - 🔄 Supports common Rust types (
String
,u8
,u16
,i32
,f64
,Option
,Vec<T>
,Vec<Option<T>>
, etc.). - ❌ Compile-time errors for unsupported types.
- ✅ Default values for missing fields.
- ⚙ Supports nested struct parsing with
.
notation.
🛆 Installation
Add DoLess
to your Cargo.toml
:
[dependencies]
doless = "0.3.0"
👺 Usage
Basic Struct Mapping
use doless::FromHashMap;
use std::collections::HashMap;
#[derive(FromHashMap, Debug, PartialEq)]
struct Car {
model: String,
year: u16,
}
fn main() {
let mut data = HashMap::new();
data.insert("model".to_string(), "GT-R".to_string());
data.insert("year".to_string(), "2023".to_string());
let car: Car = Car::from(data);
println!("Car: Model = {}, Year = {}", car.model, car.year);
}
Nested Struct Support
use doless::FromHashMap;
use std::collections::HashMap;
#[derive(FromHashMap, Debug)]
struct Car {
model: String,
brand: String,
number: u8,
details: CarDetails, // ✅ Nested Struct Support
}
#[derive(FromHashMap, Debug)]
struct CarDetails {
name: String,
description: String,
}
fn main() {
let mut data = HashMap::new();
data.insert("model".to_string(), "GT-R".to_string());
data.insert("brand".to_string(), "Nissan".to_string());
data.insert("number".to_string(), "8".to_string());
// ✅ Nested Fields with Prefix Notation
data.insert("details.name".to_string(), "Skyline".to_string());
data.insert("details.description".to_string(), "Legendary Sports Car".to_string());
let car: Car = Car::from(data);
println!("{:?}", car);
}
Support for Vec<T>
and Vec<Option<T>>
use doless::FromHashMap;
use std::collections::HashMap;
#[derive(FromHashMap, Debug)]
struct ItemCollection {
items: Vec<String>, // ✅ Supports Vec<String>
numbers: Vec<u8>, // ✅ Supports Vec<u8>
optional_items: Vec<Option<String>>, // ✅ Supports Vec<Option<T>>
}
fn main() {
let mut data = HashMap::new();
data.insert("items".to_string(), "apple, banana, orange".to_string());
data.insert("numbers".to_string(), "1,2,3".to_string());
data.insert("optional_items".to_string(), "apple,,orange".to_string()); // Empty string = None
let collection: ItemCollection = ItemCollection::from(data);
println!("{:?}", collection);
}
Expected Output
ItemCollection {
items: ["apple", "banana", "orange"],
numbers: [1, 2, 3],
optional_items: [Some("apple"), None, Some("orange")],
}
🚀 Why Use DoLess?
- Simple & Lightweight — No runtime dependencies, just pure Rust.
- Declarative API — Uses procedural macros to generate efficient
From<HashMap<String, String>>
implementations. - Type-Safe & Extensible — Ensures correct conversions and supports nesting.
⚙ Roadmap
- Basic primitive types mapping
- Nested struct support
-
Vec<T>
andVec<Option<T>>
support - Custom conversion support
- Error handling improvements
Happy coding! ✨
Dependencies
~250–690KB
~16K SLoC