use std::{fs, path::PathBuf, time::Duration};
pub enum DevicePowerControl {
Auto,
On,
}
pub enum DevicePowerStatus {
Suspended,
Suspending,
Resuming,
Active,
FatalError,
Unsupported,
}
mod _ignore {
#![allow(dead_code)]
use super::*;
pub struct DevicePowerWakeup {}
impl DevicePowerWakeup {
pub fn can_wakeup(&self) -> bool {
todo!()
}
pub fn count(&self) -> u32 {
todo!()
}
pub fn count_active(&self) -> u32 {
todo!()
}
pub fn count_abort(&self) -> u32 {
todo!()
}
pub fn count_expired(&self) -> u32 {
todo!()
}
pub fn active(&self) -> bool {
todo!()
}
pub fn total_time(&self) -> Duration {
todo!()
}
pub fn max_time(&self) -> Duration {
todo!()
}
pub fn last_time(&self) -> Duration {
todo!()
}
pub fn prevent_sleep_time(&self) -> Duration {
todo!()
}
}
}
pub trait Device {
fn device_path(&self) -> PathBuf;
fn kernel_name(&self) -> String {
self.device_path()
.file_stem()
.unwrap()
.to_str()
.unwrap()
.into()
}
fn driver(&self) -> Option<String> {
fs::read_link(self.device_path().join("driver"))
.map(|s| s.file_stem().unwrap().to_str().unwrap().into())
.ok()
}
fn subsystem(&self) -> String {
fs::read_link(self.device_path().join("subsystem"))
.map(|s| s.file_stem().unwrap().to_str().unwrap().into())
.unwrap()
}
}
pub trait DevicePower {
fn can_wakeup(&self) -> Option<bool>;
fn control(&self) -> DevicePowerControl;
fn autosuspend_delay(&self) -> Option<Duration>;
fn status(&self) -> DevicePowerStatus;
fn r#async(&self) -> bool;
}
impl<T> DevicePower for T
where
T: Device,
{
fn can_wakeup(&self) -> Option<bool> {
fs::read_to_string(self.device_path().join("power/wakeup"))
.map(|s| match s.trim() {
"enabled" => true,
"disabled" => false,
_ => panic!("Unexpected `power/wakeup` value"),
})
.ok()
}
fn control(&self) -> DevicePowerControl {
fs::read_to_string(self.device_path().join("power/control"))
.map(|s| match s.trim() {
"auto" => DevicePowerControl::Auto,
"on" => DevicePowerControl::On,
_ => panic!("Unexpected `power/control` value"),
})
.unwrap()
}
fn autosuspend_delay(&self) -> Option<Duration> {
fs::read_to_string(self.device_path().join("power/autosuspend_delay_ms"))
.map(|s| Duration::from_millis(s.trim().parse().unwrap()))
.ok()
}
fn status(&self) -> DevicePowerStatus {
fs::read_to_string(self.device_path().join("power/runtime_status"))
.map(|s| match s.trim() {
"suspended" => DevicePowerStatus::Suspended,
"suspending" => DevicePowerStatus::Suspending,
"resuming" => DevicePowerStatus::Resuming,
"active" => DevicePowerStatus::Active,
"error" => DevicePowerStatus::FatalError,
"unsupported" => DevicePowerStatus::Unsupported,
_ => panic!("Unexpected `power/runtime_status` value"),
})
.unwrap()
}
fn r#async(&self) -> bool {
fs::read_to_string(self.device_path().join("power/async"))
.map(|s| match s.trim() {
"enabled" => true,
"disabled" => false,
_ => panic!("Unexpected `power/async` value"),
})
.unwrap()
}
}