Skip to main content

lattice_notify/
options.rs

1//! NOTIF.1e: the notification subsystem's typed options.
2//!
3//! Owned here rather than in `lattice-config` for the reason
4//! `lattice-diff`'s are — the subsystem owns its full surface, options
5//! included. Self-register via `linkme`; the host's
6//! `init_from_linkme()` walks the global slice at boot.
7
8/// Validator for `notifications.max-visible`. `0` is meaningful — it
9/// silences the corner entirely without unregistering the subsystem, so
10/// `*messages*` still records everything. The ceiling stops a value
11/// that would paper over the whole editor.
12#[allow(clippy::ptr_arg)]
13fn validate_max_visible(n: &i64) -> Result<(), String> {
14    if *n >= 0 && *n <= 20 {
15        Ok(())
16    } else {
17        Err(format!(
18            "notifications.max-visible must be in range [0, 20], got {n}"
19        ))
20    }
21}
22
23/// Validator for `notifications.timeout`. Must be positive: `0` would
24/// mean a notification that expires before it can be read, which is
25/// indistinguishable from the invisible-completion bug the subsystem
26/// exists to remove. Use `max-visible = 0` to silence the corner.
27#[allow(clippy::ptr_arg)]
28fn validate_timeout(n: &i64) -> Result<(), String> {
29    if *n >= 1 && *n <= 3600 {
30        Ok(())
31    } else {
32        Err(format!(
33            "notifications.timeout must be in range [1, 3600] seconds, got {n} \
34             (use `notifications.max-visible = 0` to show none)"
35        ))
36    }
37}
38
39lattice_config::options! {
40    group = lattice_config::Notifications;
41
42    /// How many notifications the corner shows at once. The rest queue,
43    /// and the stack shows `+N more`.
44    ///
45    /// `0` shows none — the subsystem keeps running and `*messages*`
46    /// keeps its record, so nothing is lost, it is just silent.
47    #[name("notifications.max-visible")]
48    #[validate(validate_max_visible)]
49    pub NotificationsMaxVisible: i64 = 3;
50
51    /// Seconds an **info** notification stays up.
52    ///
53    /// Warnings last twice this and errors four times it, and that
54    /// ratio is deliberate rather than three separate knobs: an error
55    /// you blink past is an error you will hit again, so raising this
56    /// must not leave errors relatively shorter than the successes
57    /// around them. One number keeps them ordered by construction.
58    #[name("notifications.timeout")]
59    #[validate(validate_timeout)]
60    pub NotificationsTimeout: i64 = 4;
61
62    /// Which corner the stack anchors to.
63    #[name("notifications.corner")]
64    pub NotificationsCorner: String = "bottom-right".to_string();
65}