dispatch_map

💡 Polymorphic Map dispatch, declarative deserialization, type safety, business structure and configuration perfectly aligned!
🚀 Background & Motivation
You are developing an aggregate payment platform, and each payment channel has its own unique Rust config type, for example:
You want to configure these structures in .toml/.yaml/.json files, achieving "type-driven, clear structure".
⚠️ Pain Point: The Disaster of Default Serialization Structure
When using #[derive(Serialize, Deserialize)] directly, you expect to get:
[]
= "sk_test_123"
= "us"
But what you actually get is:
[]
= "sk_test_123"
= "us"
Each enum layer adds an extra nesting!
Maintaining this is extremely redundant, and deserialization becomes mechanical and repetitive.
🛠️ Traditional Solution: Handwritten Glue
You have to write such "deserialization glue":
- Each channel needs a handwritten match, and maintenance cost increases rapidly as types grow.
- Serialization and deserialization are hard to make reversible, and it's easy to make type errors or miss branches.
✨ Advanced Solution: Use #[serde(untagged)] to Optimize Nesting
You can add one line to ChannelConfig:
This lets serde automatically unbox, leaving only one layer of nesting and a clean config structure.
🧩 dispatch_map: Declarative Dispatch, Ultimate Simplicity
With dispatch_map, you can declare glue in one line, all type dispatch is automatic, no need to write tedious match by hand.
1️⃣ Type declarations are as elegant as business modeling
use ;
use ;
use ;
// Other channels similar...
2️⃣ Glue dispatch only needs one macro line, type safe
dispatch_pattern!
3️⃣ Business config uses DispatchMap, no need for custom deserializer
🎯 Advantages at a Glance
- Type safety: Type-driven throughout, no more handwritten match.
- Minimal glue: Adding a new channel only needs one more line, no redundant code to maintain.
- Reversible serialization/deserialization: Clean config structure, format and business types perfectly aligned.
- Generic friendly, IDE completion always available.
- Compatible with main serde formats: toml, yaml, json all supported.
- No performance loss: All glue is generated at compile time, no runtime dispatch.
🧪 Complete Example (as unit test)
let src = r#"
[channels.Stripe]
api_key = "sk_test_123"
region = "us"
[channels.AliPay]
app_id = "2023"
private_key = "..."
"#;
let cfg: AppConfig = from_str.unwrap;
assert!;
💡 FAQ
- Q: Does it support other key/value types?
As long as the key implementsEq + Hash + Deserialize + Serialize, and the value can be glued, it works. - Q: Does it support multi-level nesting/recursive structures?
Any combination and nesting is possible, fully generic friendly. - Q: Compatible with serde features?
Fully compatible with the serde ecosystem.
🏆 Summary
dispatch_map makes polymorphic config serialization/deserialization simple and type-safe, declaration is glue, focus on business design, config experience as you wish!
Welcome star, PR, and questions! If you find it useful, don't forget to leave a like on crates.io ⭐️!