mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-08 05:08:31 -04:00
Start implementing new LIST cmd. Fix version cmd
This commit is contained in:
parent
cc409f853b
commit
8153d848c0
5 changed files with 187 additions and 32 deletions
|
@ -1,7 +1,7 @@
|
|||
use std::convert::TryInto;
|
||||
use std::env;
|
||||
|
||||
use rups::blocking::Connection;
|
||||
use rups::blocking::Client;
|
||||
use rups::{Auth, ConfigBuilder};
|
||||
|
||||
fn main() -> rups::Result<()> {
|
||||
|
@ -22,7 +22,7 @@ fn main() -> rups::Result<()> {
|
|||
.with_debug(false) // Turn this on for debugging network chatter
|
||||
.build();
|
||||
|
||||
let mut conn = Connection::new(&config)?;
|
||||
let mut conn = Client::new(&config)?;
|
||||
|
||||
// Get server information
|
||||
println!("NUT server:");
|
||||
|
@ -34,34 +34,34 @@ fn main() -> rups::Result<()> {
|
|||
for (name, description) in conn.list_ups()? {
|
||||
println!("\t- Name: {}", name);
|
||||
println!("\t Description: {}", description);
|
||||
println!("\t Number of logins: {}", conn.get_num_logins(&name)?);
|
||||
|
||||
// Get list of mutable variables
|
||||
let mutable_vars = conn.list_mutable_vars(&name)?;
|
||||
|
||||
// List UPS variables (key = val)
|
||||
println!("\t Mutable Variables:");
|
||||
for var in mutable_vars.iter() {
|
||||
println!("\t\t- {}", var);
|
||||
println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||
}
|
||||
|
||||
// List UPS immutable properties (key = val)
|
||||
println!("\t Immutable Properties:");
|
||||
for var in conn.list_vars(&name)? {
|
||||
if mutable_vars.iter().any(|v| v.name() == var.name()) {
|
||||
continue;
|
||||
}
|
||||
println!("\t\t- {}", var);
|
||||
println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||
}
|
||||
|
||||
// List UPS commands
|
||||
println!("\t Commands:");
|
||||
for cmd in conn.list_commands(&name)? {
|
||||
let description = conn.get_command_description(&name, &cmd)?;
|
||||
println!("\t\t- {} ({})", cmd, description);
|
||||
}
|
||||
// println!("\t Number of logins: {}", conn.get_num_logins(&name)?);
|
||||
//
|
||||
// // Get list of mutable variables
|
||||
// let mutable_vars = conn.list_mutable_vars(&name)?;
|
||||
//
|
||||
// // List UPS variables (key = val)
|
||||
// println!("\t Mutable Variables:");
|
||||
// for var in mutable_vars.iter() {
|
||||
// println!("\t\t- {}", var);
|
||||
// println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||
// }
|
||||
//
|
||||
// // List UPS immutable properties (key = val)
|
||||
// println!("\t Immutable Properties:");
|
||||
// for var in conn.list_vars(&name)? {
|
||||
// if mutable_vars.iter().any(|v| v.name() == var.name()) {
|
||||
// continue;
|
||||
// }
|
||||
// println!("\t\t- {}", var);
|
||||
// println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||
// }
|
||||
//
|
||||
// // List UPS commands
|
||||
// println!("\t Commands:");
|
||||
// for cmd in conn.list_commands(&name)? {
|
||||
// let description = conn.get_command_description(&name, &cmd)?;
|
||||
// println!("\t\t- {} ({})", cmd, description);
|
||||
// }
|
||||
}
|
||||
|
||||
// Gracefully shut down the connection using the `LOGOUT` command
|
||||
|
|
|
@ -107,4 +107,10 @@ impl Client {
|
|||
fn enable_ssl(self) -> crate::Result<Self> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
/// Gracefully closes the connection.
|
||||
pub fn close(mut self) -> crate::Result<()> {
|
||||
self.exec_logout()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
149
rups/src/cmd.rs
149
rups/src/cmd.rs
|
@ -743,6 +743,132 @@ macro_rules! implement_client_action_commands {
|
|||
};
|
||||
}
|
||||
|
||||
/// A macro for implementing client action commands that return a string.
|
||||
///
|
||||
/// Each function should return the sentence to pass.
|
||||
macro_rules! implement_client_simple_commands {
|
||||
(
|
||||
$(
|
||||
$(#[$attr:meta])+
|
||||
$vis:vis fn $name:ident($($argname:ident: $argty:ty),*) -> String {
|
||||
$cmd:block
|
||||
}
|
||||
)*
|
||||
) => {
|
||||
impl crate::blocking::Client {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[allow(dead_code)]
|
||||
$vis fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<String> {
|
||||
use crate::proto::{Sentence, ServerSentences::*};
|
||||
self.stream
|
||||
.write_sentence(&$cmd)?;
|
||||
self.stream
|
||||
.read_literal()
|
||||
.map(|s| String::from(s.trim_end_matches('\n')))
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
impl crate::tokio::Client {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[allow(dead_code)]
|
||||
$vis async fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<String> {
|
||||
use crate::proto::{Sentence, ServerSentences::*};
|
||||
self.stream
|
||||
.write_sentence(&$cmd)
|
||||
.await?;
|
||||
self.stream
|
||||
.read_literal()
|
||||
.await
|
||||
.map(|s| String::from(s.trim_end_matches('\n')))
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A macro for implementing client action commands that return a list of objects.
|
||||
///
|
||||
/// Each function should return:
|
||||
/// 1. The sentence to execute the query
|
||||
/// 2. The expected 'BEGIN' sentence
|
||||
/// 3. The expected return sentence
|
||||
/// 4. The mapper for individual items
|
||||
/// 5. The expected 'END' sentence
|
||||
macro_rules! implement_client_list_commands {
|
||||
(
|
||||
$(
|
||||
$(#[$attr:meta])+
|
||||
$vis:vis fn $name:ident($($argname:ident: $argty:ty),*) -> $ret:ty {
|
||||
$cmd:expr,
|
||||
$begin:pat_param,
|
||||
$itemsentence:pat_param,
|
||||
$mapper:block,
|
||||
$end:pat_param
|
||||
}
|
||||
)*
|
||||
) => {
|
||||
impl crate::blocking::Client {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[allow(dead_code)]
|
||||
$vis fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<$ret> {
|
||||
use crate::proto::{Sentence, ClientSentences, ClientSentences::*, ServerSentences::*};
|
||||
self.stream
|
||||
.write_sentence(&$cmd)?;
|
||||
self.stream
|
||||
.read_sentence::<ClientSentences>()?
|
||||
.matching(|s| matches!(s, $begin))?;
|
||||
let sentences: Vec<ClientSentences> = self.stream
|
||||
.read_sentences_until(|s| matches!(s, $end))?;
|
||||
sentences
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
match s {
|
||||
$itemsentence => Ok($mapper),
|
||||
_ => Err(crate::Error::Nut(crate::NutError::UnexpectedResponse)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
impl crate::tokio::Client {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
#[allow(dead_code)]
|
||||
$vis async fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<$ret> {
|
||||
use crate::proto::{Sentence, ClientSentences, ClientSentences::*, ServerSentences::*};
|
||||
self.stream
|
||||
.write_sentence(&$cmd)
|
||||
.await?;
|
||||
self.stream
|
||||
.read_sentence::<ClientSentences>()
|
||||
.await?
|
||||
.matching(|s| matches!(s, $begin))?;
|
||||
let sentences: Vec<ClientSentences> = self.stream
|
||||
.read_sentences_until(|s| matches!(s, $end))
|
||||
.await?;
|
||||
sentences
|
||||
.into_iter()
|
||||
.map(|s| {
|
||||
match s {
|
||||
$itemsentence => Ok($mapper),
|
||||
_ => Err(crate::Error::Nut(crate::NutError::UnexpectedResponse)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
implement_list_commands! {
|
||||
/// Queries a list of UPS devices.
|
||||
pub fn list_ups() -> Vec<(String, String)> {
|
||||
|
@ -917,3 +1043,26 @@ implement_client_action_commands! {
|
|||
{ StartTLSOk {} }
|
||||
}
|
||||
}
|
||||
|
||||
implement_client_simple_commands! {
|
||||
/// Queries the network protocol version.
|
||||
pub fn get_network_version() -> String {
|
||||
{ QueryNetworkVersion {} }
|
||||
}
|
||||
|
||||
/// Queries the server NUT version.
|
||||
pub fn get_server_version() -> String {
|
||||
{ QueryVersion {} }
|
||||
}
|
||||
}
|
||||
|
||||
implement_client_list_commands! {
|
||||
/// Queries the network protocol version.
|
||||
pub fn list_ups() -> Vec<(String, String)> {
|
||||
QueryListUps {},
|
||||
BeginListUps {},
|
||||
RespondUps {ups_name, description},
|
||||
{ (ups_name, description) },
|
||||
EndListUps {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ impl_words! {
|
|||
/// Represents a variable.
|
||||
Var("VAR"),
|
||||
/// Client requests the server version.
|
||||
Version("VERSION"),
|
||||
Version("VER"),
|
||||
}
|
||||
|
||||
use crate::{Error, NutError};
|
||||
|
|
|
@ -481,7 +481,7 @@ mod tests {
|
|||
Sentences::QueryHelp {}
|
||||
);
|
||||
test_encode_decode!(
|
||||
["VERSION"] <=>
|
||||
["VER"] <=>
|
||||
Sentences::QueryVersion {}
|
||||
);
|
||||
test_encode_decode!(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue