#![deny(missing_docs)]
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
pub const BACKLIGHT_PATH: &str = "/sys/class/backlight";
pub const BL_POWER: &str = "bl_power";
#[derive(Debug)]
pub struct Device {
path: PathBuf,
bl_power: PathBuf,
}
impl Device {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
let path: &Path = path.as_ref();
Self {
path: path.to_path_buf(),
bl_power: path.join(BL_POWER),
}
}
#[allow(unused)]
fn custom<P: AsRef<Path>, Q: AsRef<Path>>(path: P, bl_power: Option<Q>) -> Self {
let path: &Path = path.as_ref();
match bl_power {
Some(q) => Device {
path: path.to_path_buf(),
bl_power: path.join(q),
},
None => Device {
path: path.to_path_buf(),
bl_power: path.join(BL_POWER),
},
}
}
pub fn path(&self) -> &Path {
&self.path
}
pub fn bl_power(&self) -> &Path {
&self.bl_power
}
pub fn toggle(&self) -> io::Result<i32> {
let old_value = read_i32(&self.bl_power)?;
let new_value = if old_value == 0 { 1 } else { 0 };
write_i32(&self.bl_power, new_value)?;
Ok(new_value)
}
}
pub struct DeviceIter {
readdir: Option<fs::ReadDir>,
}
impl DeviceIter {
pub fn new<P: AsRef<Path>>(path: P) -> Self {
let readdir = match fs::read_dir(&path) {
Ok(iter) => Some(iter),
Err(_) => None,
};
Self { readdir }
}
}
impl Default for DeviceIter {
fn default() -> Self {
Self::new(Path::new(BACKLIGHT_PATH))
}
}
impl Iterator for DeviceIter {
type Item = Device;
fn next(&mut self) -> Option<Self::Item> {
match self.readdir {
Some(ref mut diriter) => diriter
.filter(|entry| entry.is_ok())
.map(|entry| entry.unwrap().path())
.find(|path| bl_power(path).is_file())
.map(|p| Device::new(&p)),
_ => None,
}
}
}
pub fn iterate_devices<P: AsRef<Path>>(dir: P) -> io::Result<impl Iterator<Item = Device>> {
let diriter = fs::read_dir(dir)?;
Ok(diriter
.filter(|entry| entry.is_ok())
.map(|entry| entry.unwrap().path())
.filter(|path| bl_power(path).is_file())
.map(|p| Device::new(&p)))
}
fn bl_power(path: &Path) -> PathBuf {
path.join(BL_POWER)
}
fn read_i32(path: &Path) -> io::Result<i32> {
fs::read_to_string(path)?
.trim()
.parse::<i32>()
.map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "cannot parse i32"))
}
fn write_i32(path: &Path, value: i32) -> io::Result<()> {
fs::write(path, value.to_string())
}