Skip to main content

login_poweroff_reboot/
lib.rs

1pub use dbus::Error;
2use std::string::ToString;
3use std::time::{SystemTime, SystemTimeError, UNIX_EPOCH};
4use strum::Display;
5
6mod login;
7
8const DESTINATION: &str = "org.freedesktop.login1";
9const PATH: &str = "/org/freedesktop/login1";
10const TIMEOUT_SECONDS: u64 = 5;
11
12#[derive(Display)]
13#[strum(serialize_all = "lowercase")]
14pub enum Shutdown {
15    Poweroff,
16    Reboot,
17}
18
19fn time(delay_millis: u64) -> Result<u64, SystemTimeError> {
20    SystemTime::now()
21        .duration_since(UNIX_EPOCH)
22        .map(|now| now.as_millis() as u64 + delay_millis)
23}
24
25pub fn shutdown(shutdown: Shutdown) -> impl Fn(u64) -> Result<(), Error> {
26    move |delay_milliseconds| {
27        use login::OrgFreedesktopLogin1Manager;
28
29        let connection = dbus::blocking::LocalConnection::new_system()?;
30        let proxy = connection.with_proxy(
31            DESTINATION,
32            PATH,
33            std::time::Duration::from_secs(TIMEOUT_SECONDS),
34        );
35        if let Ok(millis_since_epoch) = time(delay_milliseconds) {
36            proxy.schedule_shutdown(&shutdown.to_string(), millis_since_epoch)?;
37        };
38
39        Ok(())
40    }
41}