enum2contract
enum2contract is a no_std compatible rust derive macro that lets users specify contracts for pub/sub style messaging using strongly typed rust enums.
Each generated payload derives Default, Debug, Clone, and PartialEq, and gets JSON (to_json/from_json) and binary (to_bytes/from_bytes) conversion methods.
Usage
Add this to your Cargo.toml:
enum2contract = "0.3"
No other dependencies are required; the crate re-exports serde, serde_json, and postcard for the generated code.
Example:
use enum2contract::EnumContract;
#[derive(EnumContract)]
pub enum Message {
#[topic("notify/{group}")]
Notify,
#[topic("notify_all")]
NotifyAll,
#[topic("system/{id}/start/{mode}")]
Start { immediate: bool, timeout: u64 },
}
#[test]
fn topic() {
assert_eq!(Message::notify_topic("subset"), "notify/subset");
assert_eq!(Message::notify_all_topic(), "notify_all");
assert_eq!(
Message::start_topic(&3.to_string(), "idle"),
"system/3/start/idle"
);
}
#[test]
fn message() {
assert_eq!(
Message::notify("subgroup"),
("notify/subgroup".to_string(), NotifyPayload::default())
);
assert_eq!(
Message::notify_all(),
("notify_all".to_string(), NotifyAllPayload::default())
);
assert_eq!(
Message::start(&3.to_string(), "idle"),
("system/3/start/idle".to_string(), StartPayload::default())
);
}
#[test]
fn notify_payload_from_json_with_data() {
let json = r#"{"immediate":true,"timeout":40}"#;
let payload = StartPayload::from_json(json).unwrap();
assert_eq!(
payload,
StartPayload {
immediate: true,
timeout: 40,
}
);
}
#[test]
fn start_payload_binary_round_trip() {
let payload = StartPayload {
immediate: true,
timeout: 40,
};
let bytes = payload.to_bytes().unwrap();
assert_eq!(StartPayload::from_bytes(&bytes).unwrap(), payload);
}
This crate is #![no_std] compatible but requires alloc.