diff --git a/nut-client/src/cmd.rs b/nut-client/src/cmd.rs index 44dc13b..def4369 100644 --- a/nut-client/src/cmd.rs +++ b/nut-client/src/cmd.rs @@ -1,8 +1,8 @@ use core::fmt; - -use crate::{ClientError, NutError, Variable, VariableDefinition}; use std::convert::TryFrom; +use crate::{ClientError, NutError, Variable, VariableDefinition, VariableRange}; + #[derive(Debug, Clone)] pub enum Command<'a> { Get(&'a [&'a str]), @@ -105,6 +105,10 @@ pub enum Response { /// /// Params: (variable name, variable types) Type(String, Vec), + /// A variable range (RANGE) response. + /// + /// Params: (variable range) + Range(VariableRange), } impl Response { @@ -371,6 +375,37 @@ impl Response { let types = args; Ok(Response::Type(name, types)) } + "RANGE" => { + let _device = if args.is_empty() { + Err(ClientError::from(NutError::Generic( + "Unspecified RANGE device in response".into(), + ))) + } else { + Ok(args.remove(0)) + }?; + let _name = if args.is_empty() { + Err(ClientError::from(NutError::Generic( + "Unspecified RANGE name in response".into(), + ))) + } else { + Ok(args.remove(0)) + }?; + let min = if args.is_empty() { + Err(ClientError::from(NutError::Generic( + "Unspecified RANGE min in response".into(), + ))) + } else { + Ok(args.remove(0)) + }?; + let max = if args.is_empty() { + Err(ClientError::from(NutError::Generic( + "Unspecified RANGE max in response".into(), + ))) + } else { + Ok(args.remove(0)) + }?; + Ok(Response::Range(VariableRange(min, max))) + } _ => Err(NutError::UnknownResponseType(cmd_name).into()), } } @@ -477,6 +512,14 @@ impl Response { Err(NutError::UnexpectedResponse.into()) } } + + pub fn expect_range(&self) -> crate::Result { + if let Self::Range(range) = &self { + Ok(range.to_owned()) + } else { + Err(NutError::UnexpectedResponse.into()) + } + } } /// A macro for implementing `LIST` commands. @@ -716,6 +759,14 @@ implement_list_commands! { { |row: Response| row.expect_cmd() }, ) } + + /// Queries the possible ranges of a UPS variable. + pub fn list_var_range(ups_name: &str, variable: &str) -> Vec { + ( + { &["RANGE", ups_name, variable] }, + { |row: Response| row.expect_range() }, + ) + } } implement_get_commands! { diff --git a/nut-client/src/var.rs b/nut-client/src/var.rs index 734a2da..ff41fd0 100644 --- a/nut-client/src/var.rs +++ b/nut-client/src/var.rs @@ -277,6 +277,10 @@ impl TryFrom<(A, Vec<&str>)> for VariableDefinition { } } +/// A range of values for a variable. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct VariableRange(pub String, pub String); + #[cfg(test)] mod tests { use std::iter::FromIterator;