ferogram-derive 0.3.8

Procedural macros for ferogram - #[derive(FsmState)]
Documentation

ferogram-derive

Procedural macros for the ferogram workspace. Currently exposes #[derive(FsmState)].

Crates.io Telegram Channel docs.rs License: MIT OR Apache-2.0

Most users get this through ferogram with the derive feature flag. Direct usage is only needed when building on top of the FSM layer directly.


Installation

Via the ferogram crate (recommended):

[dependencies]
ferogram = { version = "0.3.8", features = ["derive"] }

Or directly:

[dependencies]
ferogram-derive = "0.3.8"

#[derive(FsmState)]

Implements the ferogram::fsm::FsmState trait for an enum.

Restrictions: only unit variants are supported. Tuple or struct variants produce a compile error.

What gets generated:

  • as_key(&self) -> String converts the variant name to a string.
  • from_key(key: &str) -> Option<Self> parses the variant name back into the enum.
use ferogram::FsmState;

#[derive(FsmState, Clone, Debug, PartialEq)]
enum RegistrationState {
    Start,
    WaitingName,
    WaitingPhone,
    WaitingCity,
    Done,
}

The generated impl:

impl ferogram::fsm::FsmState for RegistrationState {
    fn as_key(&self) -> String {
        match self {
            Self::Start       => "Start",
            Self::WaitingName => "WaitingName",
            // ...
        }
        .to_string()
    }

    fn from_key(key: &str) -> Option<Self> {
        match key {
            "Start"       => Some(Self::Start),
            "WaitingName" => Some(Self::WaitingName),
            // ...
            _ => None,
        }
    }
}

Keys are the variant names as written in source. Renaming a variant changes its key and breaks any stored state.


Using FsmState in a dispatcher

use ferogram::{FsmState, fsm::MemoryStorage, filters::text};
use std::sync::Arc;

#[derive(FsmState, Clone, Debug, PartialEq)]
enum Form { Name, Age, Done }

dp.with_state_storage(Arc::new(MemoryStorage::new()));

dp.on_message_fsm(text(), Form::Name, |msg, state| async move {
    state.set_data("name", msg.text().unwrap()).await.ok();
    state.transition(Form::Age).await.ok();
    msg.reply("How old are you?").await.ok();
});

dp.on_message_fsm(text(), Form::Age, |msg, state| async move {
    let name = state.get_data("name").await.unwrap_or_default();
    state.transition(Form::Done).await.ok();
    msg.reply(format!("Got it, {name}!")).await.ok();
});

Stack position

ferogram
└ ferogram-derive  <-- here (proc-macro crate, compile-time only)

License

MIT or Apache-2.0, at your option. See LICENSE-MIT and LICENSE-APACHE.

Ankit Chaubey - github.com/ankit-chaubey