mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 09:23:19 +01:00
Many updates
This commit is contained in:
@@ -5,6 +5,7 @@ use std::sync::Arc;
|
|||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||||
|
// use rog_platform::firmware_attributes::FirmwareAttributes;
|
||||||
use rog_platform::platform::{GpuMode, Properties, RogPlatform, ThrottlePolicy};
|
use rog_platform::platform::{GpuMode, Properties, RogPlatform, ThrottlePolicy};
|
||||||
use rog_platform::power::AsusPower;
|
use rog_platform::power::AsusPower;
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
@@ -94,6 +95,7 @@ impl CtrlPlatform {
|
|||||||
config_path: &Path,
|
config_path: &Path,
|
||||||
signal_context: SignalContext<'static>,
|
signal_context: SignalContext<'static>,
|
||||||
) -> Result<Self, RogError> {
|
) -> Result<Self, RogError> {
|
||||||
|
// let attrs = FirmwareAttributes::new();
|
||||||
let platform = RogPlatform::new()?;
|
let platform = RogPlatform::new()?;
|
||||||
let power = AsusPower::new()?;
|
let power = AsusPower::new()?;
|
||||||
|
|
||||||
|
|||||||
@@ -903,7 +903,7 @@
|
|||||||
device_name: "RC71L",
|
device_name: "RC71L",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse, RainbowCycle],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
@@ -912,7 +912,7 @@
|
|||||||
device_name: "RC72L",
|
device_name: "RC72L",
|
||||||
product_id: "",
|
product_id: "",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse, RainbowCycle],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
power_zones: [Keyboard],
|
power_zones: [Keyboard],
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: 2024-07-25 10:03+0000\n"
|
"POT-Creation-Date: 2024-08-26 05:52+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|||||||
@@ -1,289 +1,288 @@
|
|||||||
// Firmware attribute interfaces
|
use std::fs::{read_dir, File};
|
||||||
// - current_value
|
use std::io::Read;
|
||||||
// - default_value
|
use std::path::Path;
|
||||||
// - display_name
|
|
||||||
// - default_value
|
|
||||||
// - possible_values
|
|
||||||
// - max_value
|
|
||||||
// - min_value
|
|
||||||
// - scalar_increment
|
|
||||||
// - type
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
fs::{read_dir, File},
|
|
||||||
io::Read,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use log::error;
|
|
||||||
|
|
||||||
use crate::error::PlatformError;
|
use crate::error::PlatformError;
|
||||||
|
|
||||||
const BASE_DIR: &str = "/sys/class/firmware-attributes/asus-bioscfg/attributes/";
|
const BASE_DIR: &str = "/sys/class/firmware-attributes/asus-armoury/attributes/";
|
||||||
|
|
||||||
fn read_i32(path: &Path) -> Result<i32, PlatformError> {
|
fn read_i32(path: &Path) -> Result<i32, PlatformError> {
|
||||||
if let Ok(mut f) = File::open(path) {
|
if let Ok(mut f) = File::open(path) {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
f.read_to_string(&mut buf)?;
|
f.read_to_string(&mut buf)?;
|
||||||
buf = buf.trim_end().to_string();
|
buf.trim()
|
||||||
if let Ok(int) = buf.parse::<i32>() {
|
.parse::<i32>()
|
||||||
return Ok(int);
|
.map_err(|_| PlatformError::ParseNum)
|
||||||
}
|
} else {
|
||||||
|
Err(PlatformError::ParseNum)
|
||||||
}
|
}
|
||||||
Err(PlatformError::ParseNum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string(path: &Path) -> Result<String, PlatformError> {
|
fn read_string(path: &Path) -> Result<String, PlatformError> {
|
||||||
if let Ok(mut f) = File::open(path) {
|
let mut f = File::open(path)?;
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
f.read_to_string(&mut buf)?;
|
f.read_to_string(&mut buf)?;
|
||||||
buf = buf.trim_end().to_string();
|
Ok(buf.trim().to_string())
|
||||||
return Ok(buf);
|
|
||||||
}
|
|
||||||
Err(PlatformError::ParseNum)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attr_path_if_exists(mut base_path: PathBuf, attr: &str) -> Option<PathBuf> {
|
#[derive(Debug, Default, PartialEq, PartialOrd)]
|
||||||
base_path.push(attr);
|
pub enum AttrValue {
|
||||||
if base_path.exists() {
|
Integer(i32),
|
||||||
return Some(base_path.clone());
|
String(String),
|
||||||
}
|
EnumInt(Vec<i32>),
|
||||||
None
|
EnumStr(Vec<String>),
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct AttrInteger {
|
|
||||||
current: PathBuf,
|
|
||||||
default: Option<PathBuf>,
|
|
||||||
min: Option<PathBuf>,
|
|
||||||
max: Option<PathBuf>,
|
|
||||||
scalar_inc: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttrInteger {
|
|
||||||
pub fn current_value(&self) -> Result<i32, PlatformError> {
|
|
||||||
read_i32(&self.current)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_i32(path: Option<&PathBuf>) -> Result<Option<i32>, PlatformError> {
|
|
||||||
if let Some(path) = path {
|
|
||||||
let int = read_i32(path)?;
|
|
||||||
return Ok(Some(int));
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_value(&self) -> Result<Option<i32>, PlatformError> {
|
|
||||||
Self::read_i32(self.default.as_ref())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn min_value(&self) -> Result<Option<i32>, PlatformError> {
|
|
||||||
Self::read_i32(self.min.as_ref())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn max_value(&self) -> Result<Option<i32>, PlatformError> {
|
|
||||||
Self::read_i32(self.max.as_ref())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scalar_increment(&self) -> Result<Option<i32>, PlatformError> {
|
|
||||||
Self::read_i32(self.scalar_inc.as_ref())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct AttEnumInteger {
|
|
||||||
current: PathBuf,
|
|
||||||
default: Option<PathBuf>,
|
|
||||||
possible: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttEnumInteger {
|
|
||||||
pub fn current_value(&self) -> Result<i32, PlatformError> {
|
|
||||||
read_i32(&self.current)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_value(&self) -> Result<Option<i32>, PlatformError> {
|
|
||||||
if let Some(path) = self.default.as_ref() {
|
|
||||||
let int = read_i32(path)?;
|
|
||||||
return Ok(Some(int));
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn possible_values(&self) -> Vec<i32> {
|
|
||||||
let mut output = Vec::new();
|
|
||||||
if let Some(path) = self.possible.as_ref() {
|
|
||||||
if let Ok(string) = read_string(path) {
|
|
||||||
for n in string.split(';') {
|
|
||||||
match n.parse::<i32>() {
|
|
||||||
Ok(n) => output.push(n),
|
|
||||||
Err(e) => error!("Couldn't parse num: {e:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct AttEnumString {
|
|
||||||
current: PathBuf,
|
|
||||||
default: Option<PathBuf>,
|
|
||||||
possible: Option<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttEnumString {
|
|
||||||
pub fn current_value(&self) -> Result<String, PlatformError> {
|
|
||||||
read_string(&self.current)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_value(&self) -> Result<Option<String>, PlatformError> {
|
|
||||||
if let Some(path) = self.default.as_ref() {
|
|
||||||
let string = read_string(path)?;
|
|
||||||
return Ok(Some(string));
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn possible_values(&self) -> Vec<String> {
|
|
||||||
let mut output = Vec::new();
|
|
||||||
if let Some(path) = self.possible.as_ref() {
|
|
||||||
if let Ok(string) = read_string(path) {
|
|
||||||
for n in string.split(';') {
|
|
||||||
if !n.is_empty() {
|
|
||||||
output.push(n.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub enum AttrType {
|
|
||||||
Integer(AttrInteger),
|
|
||||||
EnumInt(AttEnumInteger),
|
|
||||||
EnumStr(AttEnumString),
|
|
||||||
#[default]
|
#[default]
|
||||||
Unknown,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Attribute {
|
pub struct Attribute {
|
||||||
name: String,
|
name: String,
|
||||||
help: String,
|
help: String,
|
||||||
_base_path: PathBuf,
|
current_value: AttrValue,
|
||||||
attr_type: AttrType,
|
default_value: AttrValue,
|
||||||
|
possible_values: AttrValue,
|
||||||
|
min_value: AttrValue,
|
||||||
|
max_value: AttrValue,
|
||||||
|
scalar_increment: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attribute {
|
impl Attribute {
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
self.name.as_str()
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn help(&self) -> &str {
|
pub fn help(&self) -> &str {
|
||||||
self.help.as_str()
|
&self.help
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_value(&self) -> &AttrValue {
|
||||||
|
&self.current_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_value(&self) -> &AttrValue {
|
||||||
|
&self.default_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn possible_values(&self) -> &AttrValue {
|
||||||
|
&self.possible_values
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn min_value(&self) -> &AttrValue {
|
||||||
|
&self.min_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_value(&self) -> &AttrValue {
|
||||||
|
&self.max_value
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scalar_increment(&self) -> Option<i32> {
|
||||||
|
self.scalar_increment
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_values(
|
||||||
|
base_path: &Path,
|
||||||
|
) -> (
|
||||||
|
AttrValue,
|
||||||
|
AttrValue,
|
||||||
|
AttrValue,
|
||||||
|
AttrValue,
|
||||||
|
AttrValue,
|
||||||
|
Option<i32>,
|
||||||
|
) {
|
||||||
|
let current_value = match read_string(&base_path.join("current_value")) {
|
||||||
|
Ok(val) => {
|
||||||
|
if let Ok(int) = val.parse::<i32>() {
|
||||||
|
AttrValue::Integer(int)
|
||||||
|
} else {
|
||||||
|
AttrValue::String(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => AttrValue::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let default_value = match read_string(&base_path.join("default_value")) {
|
||||||
|
Ok(val) => {
|
||||||
|
if let Ok(int) = val.parse::<i32>() {
|
||||||
|
AttrValue::Integer(int)
|
||||||
|
} else {
|
||||||
|
AttrValue::String(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => AttrValue::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let possible_values = match read_string(&base_path.join("possible_values")) {
|
||||||
|
Ok(val) => {
|
||||||
|
if let Ok(int) = val.parse::<i32>() {
|
||||||
|
AttrValue::Integer(int)
|
||||||
|
} else if val.contains(';') {
|
||||||
|
AttrValue::EnumInt(val.split(';').filter_map(|s| s.parse().ok()).collect())
|
||||||
|
} else {
|
||||||
|
AttrValue::EnumStr(val.split(';').map(|s| s.to_string()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => AttrValue::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let min_value = read_i32(&base_path.join("min_value"))
|
||||||
|
.ok()
|
||||||
|
.map(AttrValue::Integer)
|
||||||
|
.unwrap_or_default();
|
||||||
|
let max_value = read_i32(&base_path.join("max_value"))
|
||||||
|
.ok()
|
||||||
|
.map(AttrValue::Integer)
|
||||||
|
.unwrap_or_default();
|
||||||
|
let scalar_increment = read_i32(&base_path.join("scalar_increment")).ok();
|
||||||
|
|
||||||
|
(
|
||||||
|
current_value,
|
||||||
|
default_value,
|
||||||
|
possible_values,
|
||||||
|
min_value,
|
||||||
|
max_value,
|
||||||
|
scalar_increment,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_attributes() -> Vec<Attribute> {
|
pub struct FirmwareAttributes {
|
||||||
let mut attrs = Vec::new();
|
attrs: Vec<Attribute>,
|
||||||
|
|
||||||
let dir = read_dir(BASE_DIR).unwrap();
|
|
||||||
dir.for_each(|d| {
|
|
||||||
if let Ok(base_dir) = d {
|
|
||||||
let mut attr_path = base_dir.path();
|
|
||||||
let mut attr = Attribute {
|
|
||||||
_base_path: base_dir.path(),
|
|
||||||
attr_type: AttrType::Unknown,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// TYPE
|
|
||||||
attr_path.push("type");
|
|
||||||
let mut buf = String::new();
|
|
||||||
if let Ok(mut f) = File::open(&attr_path) {
|
|
||||||
f.read_to_string(&mut buf).unwrap();
|
|
||||||
buf = buf.trim_end().to_string();
|
|
||||||
|
|
||||||
attr_path.pop();
|
|
||||||
let mut current = attr_path.clone();
|
|
||||||
current.push("current_value");
|
|
||||||
|
|
||||||
match buf.to_lowercase().as_str() {
|
|
||||||
"integer" => {
|
|
||||||
attr.attr_type = AttrType::Integer(AttrInteger {
|
|
||||||
current,
|
|
||||||
default: attr_path_if_exists(attr_path.clone(), "default_value"),
|
|
||||||
min: attr_path_if_exists(attr_path.clone(), "min_value"),
|
|
||||||
max: attr_path_if_exists(attr_path.clone(), "max_value"),
|
|
||||||
scalar_inc: attr_path_if_exists(attr_path.clone(), "scalar_increment"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// Check what the current_value type is
|
|
||||||
if let Ok(mut f) = File::open(¤t) {
|
|
||||||
let mut buf = String::new();
|
|
||||||
f.read_to_string(&mut buf).unwrap();
|
|
||||||
buf = buf.trim_end().to_string();
|
|
||||||
if buf.parse::<i32>().is_ok() {
|
|
||||||
attr.attr_type = AttrType::EnumInt(AttEnumInteger {
|
|
||||||
current,
|
|
||||||
default: attr_path_if_exists(
|
|
||||||
attr_path.clone(),
|
|
||||||
"default_value",
|
|
||||||
),
|
|
||||||
possible: attr_path_if_exists(
|
|
||||||
attr_path.clone(),
|
|
||||||
"possible_values",
|
|
||||||
),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
attr.attr_type = AttrType::EnumStr(AttEnumString {
|
|
||||||
current,
|
|
||||||
default: attr_path_if_exists(
|
|
||||||
attr_path.clone(),
|
|
||||||
"default_value",
|
|
||||||
),
|
|
||||||
possible: attr_path_if_exists(
|
|
||||||
attr_path.clone(),
|
|
||||||
"possible_values",
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// DISPLAY_NAME
|
|
||||||
attr_path.push("display_name");
|
|
||||||
if let Ok(res) = read_string(&attr_path) {
|
|
||||||
attr.help = res;
|
|
||||||
}
|
|
||||||
// DISPLAY_NAME
|
|
||||||
attr_path.pop();
|
|
||||||
attr.name = attr_path.file_name().unwrap().to_string_lossy().to_string();
|
|
||||||
|
|
||||||
attrs.push(attr);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
attrs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
|
impl FirmwareAttributes {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut attrs = Vec::new();
|
||||||
|
if let Ok(dir) = read_dir(BASE_DIR) {
|
||||||
|
for entry in dir.flatten() {
|
||||||
|
let base_path = entry.path();
|
||||||
|
let name = base_path.file_name().unwrap().to_string_lossy().to_string();
|
||||||
|
let help = read_string(&base_path.join("display_name")).unwrap_or_default();
|
||||||
|
|
||||||
|
let (
|
||||||
|
current_value,
|
||||||
|
default_value,
|
||||||
|
possible_values,
|
||||||
|
min_value,
|
||||||
|
max_value,
|
||||||
|
scalar_increment,
|
||||||
|
) = Attribute::read_values(&base_path);
|
||||||
|
|
||||||
|
attrs.push(Attribute {
|
||||||
|
name,
|
||||||
|
help,
|
||||||
|
current_value,
|
||||||
|
default_value,
|
||||||
|
possible_values,
|
||||||
|
min_value,
|
||||||
|
max_value,
|
||||||
|
scalar_increment,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Self { attrs }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attributes(&self) -> &Vec<Attribute> {
|
||||||
|
&self.attrs
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attributes_mut(&mut self) -> &mut Vec<Attribute> {
|
||||||
|
&mut self.attrs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! define_attribute_getters {
|
||||||
|
($($attr:ident),*) => {
|
||||||
|
impl FirmwareAttributes {
|
||||||
|
$(
|
||||||
|
pub fn $attr(&self) -> Option<&Attribute> {
|
||||||
|
self.attrs.iter().find(|a| a.name() == stringify!($attr))
|
||||||
|
}
|
||||||
|
|
||||||
|
concat_idents::concat_idents!(attr_mut = $attr, _mut {
|
||||||
|
pub fn attr_mut(&mut self) -> Option<&mut Attribute> {
|
||||||
|
self.attrs.iter_mut().find(|a| a.name() == stringify!($attr))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
define_attribute_getters!(
|
||||||
|
apu_mem,
|
||||||
|
cores_performance,
|
||||||
|
cores_efficiency,
|
||||||
|
ppt_pl1_spl,
|
||||||
|
ppt_pl2_sppt,
|
||||||
|
ppt_apu_sppt,
|
||||||
|
ppt_platform_sppt,
|
||||||
|
ppt_fppt,
|
||||||
|
nv_dynamic_boost,
|
||||||
|
nv_temp_target,
|
||||||
|
dgpu_base_tgp,
|
||||||
|
dgpu_tgp,
|
||||||
|
charge_mode,
|
||||||
|
boot_sound,
|
||||||
|
mcu_powersave,
|
||||||
|
panel_od,
|
||||||
|
panel_hd_mode,
|
||||||
|
egpu_connected,
|
||||||
|
egpu_enable,
|
||||||
|
dgpu_disable,
|
||||||
|
gpu_mux_mode,
|
||||||
|
mini_led_mode
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::get_attributes;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_attributes() {
|
fn find_attributes() {
|
||||||
let attrs = get_attributes();
|
let attrs = FirmwareAttributes::new();
|
||||||
for a in attrs {
|
for attr in attrs.attributes() {
|
||||||
dbg!(&a);
|
dbg!(attr.name());
|
||||||
|
match attr.name() {
|
||||||
|
"nv_dynamic_boost" => {
|
||||||
|
assert!(!attr.help().is_empty());
|
||||||
|
assert!(matches!(attr.current_value, AttrValue::Integer(_)));
|
||||||
|
if let AttrValue::Integer(val) = attr.current_value {
|
||||||
|
assert_eq!(val, 5);
|
||||||
|
}
|
||||||
|
if let AttrValue::Integer(val) = attr.default_value {
|
||||||
|
assert_eq!(val, 25);
|
||||||
|
}
|
||||||
|
assert_eq!(attr.min_value, AttrValue::Integer(0));
|
||||||
|
assert_eq!(attr.max_value, AttrValue::Integer(25));
|
||||||
|
}
|
||||||
|
"boot_sound" => {
|
||||||
|
assert!(!attr.help().is_empty());
|
||||||
|
assert!(matches!(attr.current_value, AttrValue::Integer(0)));
|
||||||
|
// dbg!(attr.current_value());
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_boot_sound() {
|
||||||
|
let attrs = FirmwareAttributes::new();
|
||||||
|
let attr = attrs
|
||||||
|
.attributes()
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.name() == "boot_sound")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(attr.name(), "boot_sound");
|
||||||
|
assert!(!attr.help().is_empty());
|
||||||
|
assert!(matches!(attr.current_value(), AttrValue::Integer(_)));
|
||||||
|
if let AttrValue::Integer(val) = attr.current_value() {
|
||||||
|
assert_eq!(*val, 0); // assuming value is 0
|
||||||
|
}
|
||||||
|
// Check other members if applicable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
pub mod firmware_attributes;
|
||||||
pub mod hid_raw;
|
pub mod hid_raw;
|
||||||
pub mod keyboard_led;
|
pub mod keyboard_led;
|
||||||
pub(crate) mod macros;
|
pub(crate) mod macros;
|
||||||
|
|||||||
Reference in New Issue
Block a user