Skip to main content

sigrun/
lib.rs

1// SPDX-License-Identifier: LGPL-2.1-or-later
2// SPDX-FileCopyrightText: 2026 Andreas Schneider <asn@cryptomilk.org>
3
4//! Sigrun — Run commands on D-Bus events.
5//!
6//! Loads rules from `~/.config/sigrun/config.toml` and reacts to D-Bus
7//! notifications, signals, and property changes by spawning configured
8//! commands.
9
10#![warn(clippy::pedantic)]
11
12pub mod config;
13pub mod error;
14pub mod executor;
15pub mod formatter;
16pub mod matcher;
17pub mod monitor;
18pub mod notification;
19pub mod property_watcher;
20pub mod signal_listener;
21pub mod watcher;
22
23#[cfg(test)]
24pub(crate) mod testutil {
25    use std::collections::HashMap;
26
27    use zbus::Message;
28    use zbus::zvariant::{OwnedValue, Value};
29
30    use crate::notification::Notification;
31
32    pub fn owned(v: Value<'_>) -> OwnedValue {
33        OwnedValue::try_from(v).expect("owned")
34    }
35
36    pub fn make_notification() -> Notification {
37        let mut hints = HashMap::new();
38        hints.insert("x-kde-eventId".into(), owned(Value::from("reminder")));
39        hints.insert("urgency".into(), owned(Value::from(1u8)));
40        hints.insert(
41            "desktop-entry".into(),
42            owned(Value::from("org.kde.kalendar")),
43        );
44
45        Notification {
46            app_name: "kalendarac".into(),
47            replaces_id: 0,
48            app_icon: "kalendar".into(),
49            summary: "Meeting in 5 minutes".into(),
50            body: "Standup with team".into(),
51            actions: vec!["default".into(), "Open".into()],
52            hints,
53            expire_timeout: -1,
54        }
55    }
56
57    pub fn make_signal_multi() -> Message {
58        Message::signal("/test", "org.test.Iface", "TestSignal")
59            .expect("valid signal")
60            .build(&(true, "hello"))
61            .expect("valid body")
62    }
63
64    pub fn make_signal_empty() -> Message {
65        Message::signal("/test", "org.test.Iface", "TestSignal")
66            .expect("valid signal")
67            .build(&())
68            .expect("valid body")
69    }
70
71    pub fn make_properties_changed(
72        iface: &str,
73        changed: HashMap<&str, Value<'_>>,
74    ) -> Message {
75        let invalidated: Vec<&str> = Vec::new();
76        Message::signal(
77            "/test",
78            "org.freedesktop.DBus.Properties",
79            "PropertiesChanged",
80        )
81        .expect("valid signal")
82        .build(&(iface, changed, invalidated))
83        .expect("valid body")
84    }
85}