Skip to main content

bot

Attribute Macro bot 

Source
#[bot]
Expand description

Derive-like attribute that turns an impl block into a runnable IRC bot.

§Custom state

Pass state = SomeType to give the bot a public state field your handlers can read:

#[derive(Default)]
struct Counter { hits: std::sync::atomic::AtomicUsize }

#[bot(state = Counter)]
impl MyBot {
    #[command("ping")]
    async fn ping(&self, ctx: ircbot::Context) -> ircbot::Result {
        let n = self.state.hits.fetch_add(1, std::sync::atomic::Ordering::Relaxed) + 1;
        ctx.reply(format!("pong #{n}"))
    }
}

The state type must implement Default (it is initialised with Default::default() by both MyBot::default() and MyBot::new) and must be Send + Sync + 'static (the bot is shared across tasks as an Arc; that bound is checked at main_loop). Because handlers receive &self, mutating state requires interior mutability — an AtomicUsize, a Mutex<…>, etc. To start from a non-default value, assign the public field after constructing: let mut bot = MyBot::new(…).await?; bot.state = …;.

Note: a SIGHUP hot-reload re-execs the binary, so in-memory state is reconstructed via Default and is not carried across the reload.

This is sugar over the lower-level API: a bot is any Arc<T: Send + Sync + 'static> passed to ircbot::internal::run_bot with a hand-built Vec<ircbot::HandlerEntry<T>>, which you can use directly when you want full control over the bot type.

§Panics

Panics at compile time if the annotated impl block does not use a simple (non-generic, non-path) type name, e.g. impl MyBot { … }.