mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
157 lines
4.4 KiB
Rust
157 lines
4.4 KiB
Rust
//! 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> {
|
|
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<bool> {
|
|
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<T>(device: &Device, attr_name: &str) -> Result<T>
|
|
where
|
|
T: std::str::FromStr,
|
|
<T as 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::<T>().map_err(|_e| PlatformError::ParseNum);
|
|
}
|
|
Err(PlatformError::AttrNotFound(attr_name.to_owned()))
|
|
}
|
|
|
|
pub fn write_attr_num<T>(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<Vec<u8>> {
|
|
if let Some(value) = device.attribute_value(attr_name) {
|
|
let tmp = value.to_string_lossy();
|
|
let tmp = tmp
|
|
.split(' ')
|
|
.map(|v| v.parse::<u8>().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<String> {
|
|
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<Vec<PlatformProfile>> {
|
|
if let Some(value) = device.attribute_value(attr_name) {
|
|
let tmp: Vec<PlatformProfile> = 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<u8> = tmp
|
|
.split(' ')
|
|
.map(|v| v.parse::<u8>().unwrap_or(0))
|
|
.collect();
|
|
assert_eq!(tmp, &[1, 2, 3, 4, 5]);
|
|
}
|
|
}
|