ircbot/handler.rs
1//! What fires a handler, and the shape of the handler itself.
2//!
3//! A [`Trigger`] describes a condition on an incoming message, or a schedule.
4//! A [`HandlerEntry`] pairs one trigger with the function to call. The bot holds
5//! a list of these entries and tests each incoming message against all of them.
6//!
7//! The `#[command]` and `#[on]` macros build these values for you. Construct
8//! them by hand only when you assemble a handler list without the macros.
9
10use std::future::Future;
11use std::pin::Pin;
12use std::sync::Arc;
13
14use crate::context::Context;
15
16/// A boxed, heap-allocated future that is `Send + 'static`.
17pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send + 'static>>;
18
19/// The type-erased handler function stored in [`HandlerEntry`].
20pub type HandlerFn<T> = Box<dyn Fn(Arc<T>, Context) -> BoxFuture<crate::Result> + Send + Sync>;
21
22/// What causes a handler to fire.
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum Trigger {
25 /// Fires when the user sends `!<name>` (optionally in a specific channel).
26 ///
27 /// When `role` is `Some`, the command only fires for senders whose
28 /// `nick!user@host` matches one of the hostmask patterns configured for that
29 /// role (see [`State::with_role`](crate::State::with_role)); unauthorized
30 /// senders are silently ignored.
31 Command {
32 /// The command word that follows the `!` prefix.
33 name: String,
34 /// When set, the command fires only in this channel or query.
35 target: Option<String>,
36 /// When set, the command fires only for senders that hold this role.
37 role: Option<String>,
38 },
39 /// Fires when an incoming PRIVMSG matches a glob pattern (`*` as wildcard).
40 Message {
41 /// The glob pattern matched against the message text.
42 pattern: String,
43 /// When set, the pattern applies only to messages sent to this target.
44 target: Option<String>,
45 },
46 /// Fires on a specific IRC event (e.g. "JOIN"), with optional target/regex filter.
47 Event {
48 /// The IRC command or numeric that fires the handler, compared
49 /// without case sensitivity.
50 event: String,
51 /// When set, the handler fires only for events on this target.
52 target: Option<String>,
53 /// When set, the trailing parameter of the message must also match this
54 /// regular expression. Its capture groups become the handler's captures.
55 regex: Option<String>,
56 },
57 /// Fires when a PRIVMSG addresses the bot by name at the start of the
58 /// message (e.g. `"botname: hello"` or `"botname, ping"`).
59 /// The text following the address prefix is provided as a capture.
60 Mention {
61 /// When set, the handler fires only for messages sent to this target.
62 target: Option<String>,
63 },
64 /// Fires on a schedule described by a cron expression. The expression uses
65 /// the 6-field Quartz format: `sec min hour day-of-month month day-of-week`
66 /// with an optional 7th `year` field. Times are evaluated in `tz`, which
67 /// must be a valid IANA timezone name (e.g. `"America/New_York"`); defaults
68 /// to `"UTC"` when not specified.
69 ///
70 /// When `target` is `None` the handler's [`Context::target`] is a
71 /// [`Target::User`](crate::Target::User) with an empty name (so its
72 /// `as_str()` is empty) and [`Context::is_channel`] returns `false`.
73 /// Handlers that need to send a message should either specify a `target` or
74 /// store the destination in their bot state.
75 ///
76 /// Example — top of every hour on weekday afternoons (Eastern time):
77 /// `"0 0 8-16 * * MON-FRI"` with `tz = "America/New_York"`
78 Cron {
79 /// The cron expression, in 6-field Quartz format with an optional
80 /// 7th `year` field.
81 schedule: String,
82 /// The IANA timezone name that the schedule is evaluated in.
83 tz: String,
84 /// When set, the handler's [`Context::target`] is this channel or user.
85 target: Option<String>,
86 },
87}
88
89/// Associates a [`Trigger`] with a handler function for a bot of type `T`.
90pub struct HandlerEntry<T> {
91 /// What causes the handler to fire.
92 pub trigger: Trigger,
93 /// The function called when the trigger matches.
94 pub handler: HandlerFn<T>,
95}