use std::fmt;
use std::os::unix::io::{AsRawFd, IntoRawFd, RawFd};
use dbus::arg::OwnedFd;
use nix::unistd;
use crate::error::LogindError;
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub enum InhibitEvent {
Shutdown,
Sleep,
Idle,
HandlePowerKey,
HandleSuspendKey,
HandleHibernateKey,
HandleLidSwitch,
}
impl InhibitEvent {
pub fn as_str(self) -> &'static str {
match self {
InhibitEvent::Shutdown => "shutdown",
InhibitEvent::Sleep => "sleep",
InhibitEvent::Idle => "idle",
InhibitEvent::HandlePowerKey => "handle-power-key",
InhibitEvent::HandleSuspendKey => "handle-suspend-key",
InhibitEvent::HandleHibernateKey => "handle-hibernate-key",
InhibitEvent::HandleLidSwitch => "handle-lid-switch",
}
}
}
impl fmt::Display for InhibitEvent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Default, Eq, PartialEq)]
pub struct InhibitEventSet(String);
impl InhibitEventSet {
pub fn new() -> InhibitEventSet {
InhibitEventSet(String::new())
}
pub fn with_event(event: InhibitEvent) -> InhibitEventSet {
InhibitEventSet(format!("{}:", event.as_str()))
}
pub fn add(&mut self, event: InhibitEvent) -> &mut InhibitEventSet {
self.0.push_str(event.as_str());
self.0.push(':');
self
}
pub fn as_str(&self) -> &str {
if self.0.is_empty() {
""
} else {
&self.0[0..self.0.len() - 1] }
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
pub enum InhibitMode {
Block,
Delay,
}
impl InhibitMode {
pub fn as_str(self) -> &'static str {
match self {
InhibitMode::Block => "block",
InhibitMode::Delay => "delay",
}
}
}
impl fmt::Display for InhibitMode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug)]
pub struct InhibitorLock {
fd: OwnedFd,
}
impl InhibitorLock {
pub(crate) fn new(fd: OwnedFd) -> InhibitorLock {
InhibitorLock { fd }
}
pub fn dup_fd(&self) -> Result<RawFd, LogindError> {
unistd::dup(self.fd.as_raw_fd()).map_err(|err| {
LogindError::inhibitor_file_error(
"Duplicating inhibitor lock file descriptor failed".to_string(),
err,
)
})
}
pub fn release(self) -> Result<(), LogindError> {
unistd::close(self.fd.into_fd()).map_err(|err| {
LogindError::inhibitor_file_error("Could not release inhibitor lock".to_string(), err)
})
}
}
impl IntoRawFd for InhibitorLock {
fn into_raw_fd(self) -> RawFd {
self.fd.into_fd()
}
}
impl fmt::Display for InhibitorLock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.fd.as_raw_fd())
}
}