//! This crate functions as a wrapper of all the relevant ASUS functionality //! on ROG, Strix, and TUF laptops. pub mod asus_armoury; pub mod backlight; pub mod cpu; pub mod error; pub mod hid_raw; pub mod keyboard_led; pub(crate) mod macros; pub mod platform; pub mod power; pub mod usb_raw; use std::path::Path; use error::{PlatformError, Result}; use log::warn; use platform::PlatformProfile; use udev::Device; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub(crate) fn to_device(sys_path: &Path) -> Result { Device::from_syspath(sys_path) .map_err(|e| PlatformError::Udev("Couldn't transform syspath to device".to_owned(), e)) } pub fn has_attr(device: &Device, attr_name: &str) -> bool { for attr in device.attributes() { if attr.name() == attr_name { return true; } } false } pub fn read_attr_bool(device: &Device, attr_name: &str) -> Result { if let Some(value) = device.attribute_value(attr_name) { let tmp = value.to_string_lossy(); if tmp.trim() == "0" { return Ok(false); } return Ok(true); } Err(PlatformError::AttrNotFound(attr_name.to_owned())) } pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<()> { let value = if value { 1 } else { 0 }; device .set_attribute_value(attr, value.to_string()) .map_err(|e| { warn!("attr write error: {e:?}"); PlatformError::IoPath(attr.into(), e) }) } pub fn read_attr_num(device: &Device, attr_name: &str) -> Result where T: std::str::FromStr, ::Err: std::fmt::Debug, { if let Some(value) = device.attribute_value(attr_name) { let tmp = value.to_string_lossy(); return tmp.parse::().map_err(|_e| PlatformError::ParseNum); } Err(PlatformError::AttrNotFound(attr_name.to_owned())) } pub fn write_attr_num(device: &mut Device, attr_name: &str, value: T) -> Result<()> where T: std::fmt::Display, { if device .set_attribute_value(attr_name, format!("{value}")) .is_err() { return Err(PlatformError::AttrNotFound(attr_name.to_owned())); } Ok(()) } pub fn read_attr_u8_array(device: &Device, attr_name: &str) -> Result> { if let Some(value) = device.attribute_value(attr_name) { let tmp = value.to_string_lossy(); let tmp = tmp .split(' ') .map(|v| v.parse::().unwrap_or(0)) .collect(); return Ok(tmp); } Err(PlatformError::AttrNotFound(attr_name.to_owned())) } pub fn write_attr_u8_array(device: &mut Device, attr: &str, values: &[u8]) -> Result<()> { let mut tmp = String::new(); for n in values { tmp.push_str(&n.to_string()); tmp.push(' '); // space padding required } tmp.pop(); device .set_attribute_value(attr, tmp.trim()) .map_err(|e| PlatformError::IoPath(attr.into(), e)) } pub fn read_attr_string(device: &Device, attr_name: &str) -> Result { if let Some(value) = device.attribute_value(attr_name) { let tmp = value.to_string_lossy().to_string(); return Ok(tmp); } Err(PlatformError::AttrNotFound(attr_name.to_owned())) } pub fn write_attr_string(device: &mut Device, attr: &str, value: &str) -> Result<()> { let tmp = value.trim(); device .set_attribute_value(attr, tmp) .map_err(|e| PlatformError::IoPath(attr.into(), e)) } pub fn read_attr_string_array(device: &Device, attr_name: &str) -> Result> { if let Some(value) = device.attribute_value(attr_name) { let tmp: Vec = value .to_string_lossy() .split(' ') .map(PlatformProfile::from) .collect(); return Ok(tmp); } Err(PlatformError::AttrNotFound(attr_name.to_owned())) } #[cfg(test)] mod tests { #[test] fn check() { let data = [ 1, 2, 3, 4, 5, ]; let mut tmp = String::new(); for n in data { tmp.push_str(&n.to_string()); tmp.push(' '); // space padding required } tmp.pop(); assert_eq!(tmp, "1 2 3 4 5"); let tmp: Vec = tmp .split(' ') .map(|v| v.parse::().unwrap_or(0)) .collect(); assert_eq!(tmp, &[1, 2, 3, 4, 5]); } }