mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-08 21:18:31 -04:00
Add support for running commands (#33)
This commit is contained in:
parent
35d40d3111
commit
821414d9cd
4 changed files with 48 additions and 8 deletions
|
@ -26,6 +26,7 @@ default = []
|
||||||
ssl = ["rustls", "rustls/dangerous_configuration", "webpki", "webpki-roots"]
|
ssl = ["rustls", "rustls/dangerous_configuration", "webpki", "webpki-roots"]
|
||||||
async = ["tokio"]
|
async = ["tokio"]
|
||||||
async-ssl = ["async", "tokio-rustls", "ssl"]
|
async-ssl = ["async", "tokio-rustls", "ssl"]
|
||||||
|
write = []
|
||||||
# a feature gate for examples
|
# a feature gate for examples
|
||||||
async-rt = ["async", "tokio/rt-multi-thread", "tokio/macros"]
|
async-rt = ["async", "tokio/rt-multi-thread", "tokio/macros"]
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@ pub enum Command<'a> {
|
||||||
NetworkVersion,
|
NetworkVersion,
|
||||||
/// Queries the server version.
|
/// Queries the server version.
|
||||||
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.
|
/// Gracefully shuts down the connection.
|
||||||
Logout,
|
Logout,
|
||||||
}
|
}
|
||||||
|
@ -33,6 +36,8 @@ impl<'a> Command<'a> {
|
||||||
Self::StartTLS => "STARTTLS",
|
Self::StartTLS => "STARTTLS",
|
||||||
Self::NetworkVersion => "NETVER",
|
Self::NetworkVersion => "NETVER",
|
||||||
Self::Version => "VER",
|
Self::Version => "VER",
|
||||||
|
#[cfg(feature = "write")]
|
||||||
|
Self::Run(_, _) => "INSTCMD",
|
||||||
Self::Logout => "LOGOUT",
|
Self::Logout => "LOGOUT",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +49,10 @@ impl<'a> Command<'a> {
|
||||||
Self::SetUsername(username) => vec![username],
|
Self::SetUsername(username) => vec![username],
|
||||||
Self::SetPassword(password) => vec![password],
|
Self::SetPassword(password) => vec![password],
|
||||||
Self::List(query) => query.to_vec(),
|
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(),
|
_ => Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -826,7 +835,7 @@ implement_simple_commands! {
|
||||||
pub fn get_network_version() -> String {
|
pub fn get_network_version() -> String {
|
||||||
(
|
(
|
||||||
{ Command::NetworkVersion },
|
{ Command::NetworkVersion },
|
||||||
{ |row: String| Ok(row) },
|
{ Ok },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +843,7 @@ implement_simple_commands! {
|
||||||
pub fn get_server_version() -> String {
|
pub fn get_server_version() -> String {
|
||||||
(
|
(
|
||||||
{ Command::Version },
|
{ Command::Version },
|
||||||
{ |row: String| Ok(row) },
|
{ Ok },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -855,3 +864,31 @@ implement_action_commands! {
|
||||||
Command::Logout
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -213,6 +213,9 @@ macro_rules! impl_sentences {
|
||||||
/// 2. the decoded sentence
|
/// 2. the decoded sentence
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// # #[macro_use] extern crate rups;
|
||||||
|
/// # fn main() {
|
||||||
|
/// # #[cfg(test)]
|
||||||
/// test_encode_decode!(
|
/// test_encode_decode!(
|
||||||
/// ["GET", "VAR", "nutdev", "test.var"] <=>
|
/// ["GET", "VAR", "nutdev", "test.var"] <=>
|
||||||
/// Sentences::QueryVar {
|
/// Sentences::QueryVar {
|
||||||
|
@ -220,6 +223,7 @@ macro_rules! impl_sentences {
|
||||||
/// var_name: "test.var".into(),
|
/// var_name: "test.var".into(),
|
||||||
/// }
|
/// }
|
||||||
/// );
|
/// );
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[allow(unused_macros)]
|
#[allow(unused_macros)]
|
||||||
macro_rules! test_encode_decode {
|
macro_rules! test_encode_decode {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
/// Well-known variable keys for NUT UPS devices.
|
/// 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 {
|
pub mod key {
|
||||||
/// Device model.
|
/// Device model.
|
||||||
pub const DEVICE_MODEL: &str = "device.model";
|
pub const DEVICE_MODEL: &str = "device.model";
|
||||||
|
@ -31,7 +31,7 @@ pub mod key {
|
||||||
|
|
||||||
/// Well-known variables for NUT UPS devices.
|
/// 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)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum Variable {
|
pub enum Variable {
|
||||||
/// Device model.
|
/// Device model.
|
||||||
|
@ -196,10 +196,8 @@ impl TryFrom<&str> for VariableType {
|
||||||
other => {
|
other => {
|
||||||
if other.starts_with("STRING:") {
|
if other.starts_with("STRING:") {
|
||||||
let size = other
|
let size = other
|
||||||
.splitn(2, ':')
|
.split_once(':')
|
||||||
.nth(1)
|
.and_then(|(_, s)| s.parse().ok())
|
||||||
.map(|s| s.parse().ok())
|
|
||||||
.flatten()
|
|
||||||
.ok_or_else(|| crate::ClientError::generic("Invalid STRING definition"))?;
|
.ok_or_else(|| crate::ClientError::generic("Invalid STRING definition"))?;
|
||||||
Ok(Self::String(size))
|
Ok(Self::String(size))
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue