Add support for running commands (#33)

This commit is contained in:
Rajasekharan Vengalil 2022-08-08 19:55:47 +05:30 committed by GitHub
parent 35d40d3111
commit 821414d9cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 8 deletions

View file

@ -26,6 +26,7 @@ default = []
ssl = ["rustls", "rustls/dangerous_configuration", "webpki", "webpki-roots"]
async = ["tokio"]
async-ssl = ["async", "tokio-rustls", "ssl"]
write = []
# a feature gate for examples
async-rt = ["async", "tokio/rt-multi-thread", "tokio/macros"]

View file

@ -18,6 +18,9 @@ pub enum Command<'a> {
NetworkVersion,
/// Queries the server version.
Version,
#[cfg(feature = "write")]
/// Run a command. Allow for on additional optional param.
Run(&'a str, Option<&'a str>),
/// Gracefully shuts down the connection.
Logout,
}
@ -33,6 +36,8 @@ impl<'a> Command<'a> {
Self::StartTLS => "STARTTLS",
Self::NetworkVersion => "NETVER",
Self::Version => "VER",
#[cfg(feature = "write")]
Self::Run(_, _) => "INSTCMD",
Self::Logout => "LOGOUT",
}
}
@ -44,6 +49,10 @@ impl<'a> Command<'a> {
Self::SetUsername(username) => vec![username],
Self::SetPassword(password) => vec![password],
Self::List(query) => query.to_vec(),
#[cfg(feature = "write")]
Self::Run(cmd, param) => param
.map(|param| vec![*cmd, param])
.unwrap_or_else(|| vec![cmd]),
_ => Vec::new(),
}
}
@ -826,7 +835,7 @@ implement_simple_commands! {
pub fn get_network_version() -> String {
(
{ Command::NetworkVersion },
{ |row: String| Ok(row) },
{ Ok },
)
}
@ -834,7 +843,7 @@ implement_simple_commands! {
pub fn get_server_version() -> String {
(
{ Command::Version },
{ |row: String| Ok(row) },
{ Ok },
)
}
}
@ -855,3 +864,31 @@ implement_action_commands! {
Command::Logout
}
}
#[cfg(feature = "write")]
impl crate::blocking::Connection {
/// Runs a command on the UPS.
pub fn run_command(&mut self, cmd: &str, param: Option<&str>) -> crate::Result<()> {
match self {
Self::Tcp(conn) => {
conn.write_cmd(Command::Run(cmd, param))?;
conn.read_response()?.expect_ok()?;
Ok(())
}
}
}
}
#[cfg(all(feature = "write", feature = "async"))]
impl crate::tokio::Connection {
/// Runs a command on the UPS.
pub async fn run_command(&mut self, cmd: &str, param: Option<&str>) -> crate::Result<()> {
match self {
Self::Tcp(conn) => {
conn.write_cmd(Command::Run(cmd, param)).await?;
conn.read_response().await?.expect_ok()?;
Ok(())
}
}
}
}

View file

@ -213,6 +213,9 @@ macro_rules! impl_sentences {
/// 2. the decoded sentence
///
/// ```
/// # #[macro_use] extern crate rups;
/// # fn main() {
/// # #[cfg(test)]
/// test_encode_decode!(
/// ["GET", "VAR", "nutdev", "test.var"] <=>
/// Sentences::QueryVar {
@ -220,6 +223,7 @@ macro_rules! impl_sentences {
/// var_name: "test.var".into(),
/// }
/// );
/// # }
/// ```
#[allow(unused_macros)]
macro_rules! test_encode_decode {

View file

@ -5,7 +5,7 @@ use std::time::Duration;
/// Well-known variable keys for NUT UPS devices.
///
/// List retrieved from: https://networkupstools.org/docs/user-manual.chunked/apcs01.html
/// List retrieved from: <https://networkupstools.org/docs/user-manual.chunked/apcs01.html>
pub mod key {
/// Device model.
pub const DEVICE_MODEL: &str = "device.model";
@ -31,7 +31,7 @@ pub mod key {
/// Well-known variables for NUT UPS devices.
///
/// List retrieved from: https://networkupstools.org/docs/user-manual.chunked/apcs01.html
/// List retrieved from: <https://networkupstools.org/docs/user-manual.chunked/apcs01.html>
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Variable {
/// Device model.
@ -196,10 +196,8 @@ impl TryFrom<&str> for VariableType {
other => {
if other.starts_with("STRING:") {
let size = other
.splitn(2, ':')
.nth(1)
.map(|s| s.parse().ok())
.flatten()
.split_once(':')
.and_then(|(_, s)| s.parse().ok())
.ok_or_else(|| crate::ClientError::generic("Invalid STRING definition"))?;
Ok(Self::String(size))
} else {