ferogram-derive 0.6.5

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

ferogram-derive

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

Crates.io Telegram Channel Telegram Chat docs.rs License

Most people get this through ferogram with the derive feature flag. Direct usage is only needed when building on top of the FSM layer without the full client.

For installation instructions see the ferogram README.


#[derive(FsmState)]

Implements the ferogram::fsm::FsmState trait for an enum. Only unit variants are supported; tuple or struct variants produce a compile error.

What gets generated: as_key(&self) -> String and from_key(key: &str) -> Option<Self>. Keys are namespaced as "module::path::EnumName::Variant" (using module_path!(), the enum name, and the variant name), so identically-named variants on different state enums -- or even identically-named enums in different modules -- don't collide in storage. Generic enums are rejected at compile time, since the key can't disambiguate different type parameter instantiations.

use ferogram::FsmState;

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

Renaming a variant, enum, or moving the enum to a different module changes its key and breaks any stored state. from_key falls back to matching the trailing "::"-segment against a variant name, so state written by pre-namespacing versions of this macro still deserializes on a best-effort basis after an upgrade.


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

This project is licensed under either the MIT License or Apache License 2.0, at your option. See LICENSE-MIT and LICENSE-APACHE for details.

Author: Ankit Chaubey (@ankit-chaubey)