#enums #macro-derive #contract #strongly-typed #pub-sub #macro #binary-encoding

macro 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. Conversion methods for JSON and binary are created for the generated payloads

7 releases

0.1.6 Apr 11, 2023
0.1.5 Apr 10, 2023
0.1.3 Mar 26, 2023

#818 in Procedural macros

Download history 56/week @ 2024-07-21 144/week @ 2024-07-28 257/week @ 2024-08-04 160/week @ 2024-08-11 229/week @ 2024-08-18 362/week @ 2024-08-25 192/week @ 2024-09-01 196/week @ 2024-09-08 246/week @ 2024-09-15 251/week @ 2024-09-22 80/week @ 2024-09-29 96/week @ 2024-10-06 16/week @ 2024-10-13 113/week @ 2024-10-20 30/week @ 2024-10-27 82/week @ 2024-11-03

243 downloads per month

MIT license

14KB
209 lines

enum2contract

github crates.io docs.rs

enum2contract is a no_std compatible rust derive macro that lets users specify contracts for pub/sub style messaging using strongly typed rust enums.

Conversion methods for JSON and binary are created for the generated payloads.

Usage

Add this to your Cargo.toml:

enum2contract = "0.1.6"
serde = { version = "1.0.158", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.94", default-features = false, features = ["alloc"] }
postcard = { version = "1.0.4", features = ["alloc"] }

Example:

use enum2contract::EnumContract;
use serde::{Deserialize, Serialize};

#[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,
        }
    );
}

This crate is #![no_std] compatible but requires alloc.

Dependencies

~1–1.8MB
~39K SLoC