mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-08 21:18: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::convert::TryInto;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use rups::blocking::Connection;
|
use rups::blocking::Client;
|
||||||
use rups::{Auth, ConfigBuilder};
|
use rups::{Auth, ConfigBuilder};
|
||||||
|
|
||||||
fn main() -> rups::Result<()> {
|
fn main() -> rups::Result<()> {
|
||||||
|
@ -22,7 +22,7 @@ fn main() -> rups::Result<()> {
|
||||||
.with_debug(false) // Turn this on for debugging network chatter
|
.with_debug(false) // Turn this on for debugging network chatter
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut conn = Connection::new(&config)?;
|
let mut conn = Client::new(&config)?;
|
||||||
|
|
||||||
// Get server information
|
// Get server information
|
||||||
println!("NUT server:");
|
println!("NUT server:");
|
||||||
|
@ -34,34 +34,34 @@ fn main() -> rups::Result<()> {
|
||||||
for (name, description) in conn.list_ups()? {
|
for (name, description) in conn.list_ups()? {
|
||||||
println!("\t- Name: {}", name);
|
println!("\t- Name: {}", name);
|
||||||
println!("\t Description: {}", description);
|
println!("\t Description: {}", description);
|
||||||
println!("\t Number of logins: {}", conn.get_num_logins(&name)?);
|
// println!("\t Number of logins: {}", conn.get_num_logins(&name)?);
|
||||||
|
//
|
||||||
// Get list of mutable variables
|
// // Get list of mutable variables
|
||||||
let mutable_vars = conn.list_mutable_vars(&name)?;
|
// let mutable_vars = conn.list_mutable_vars(&name)?;
|
||||||
|
//
|
||||||
// List UPS variables (key = val)
|
// // List UPS variables (key = val)
|
||||||
println!("\t Mutable Variables:");
|
// println!("\t Mutable Variables:");
|
||||||
for var in mutable_vars.iter() {
|
// for var in mutable_vars.iter() {
|
||||||
println!("\t\t- {}", var);
|
// println!("\t\t- {}", var);
|
||||||
println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
// println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// List UPS immutable properties (key = val)
|
// // List UPS immutable properties (key = val)
|
||||||
println!("\t Immutable Properties:");
|
// println!("\t Immutable Properties:");
|
||||||
for var in conn.list_vars(&name)? {
|
// for var in conn.list_vars(&name)? {
|
||||||
if mutable_vars.iter().any(|v| v.name() == var.name()) {
|
// if mutable_vars.iter().any(|v| v.name() == var.name()) {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
println!("\t\t- {}", var);
|
// println!("\t\t- {}", var);
|
||||||
println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
// println!("\t\t {:?}", conn.get_var_type(&name, var.name())?);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// List UPS commands
|
// // List UPS commands
|
||||||
println!("\t Commands:");
|
// println!("\t Commands:");
|
||||||
for cmd in conn.list_commands(&name)? {
|
// for cmd in conn.list_commands(&name)? {
|
||||||
let description = conn.get_command_description(&name, &cmd)?;
|
// let description = conn.get_command_description(&name, &cmd)?;
|
||||||
println!("\t\t- {} ({})", cmd, description);
|
// println!("\t\t- {} ({})", cmd, description);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gracefully shut down the connection using the `LOGOUT` command
|
// Gracefully shut down the connection using the `LOGOUT` command
|
||||||
|
|
|
@ -107,4 +107,10 @@ impl Client {
|
||||||
fn enable_ssl(self) -> crate::Result<Self> {
|
fn enable_ssl(self) -> crate::Result<Self> {
|
||||||
Ok(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! {
|
implement_list_commands! {
|
||||||
/// Queries a list of UPS devices.
|
/// Queries a list of UPS devices.
|
||||||
pub fn list_ups() -> Vec<(String, String)> {
|
pub fn list_ups() -> Vec<(String, String)> {
|
||||||
|
@ -917,3 +1043,26 @@ implement_client_action_commands! {
|
||||||
{ StartTLSOk {} }
|
{ 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.
|
/// Represents a variable.
|
||||||
Var("VAR"),
|
Var("VAR"),
|
||||||
/// Client requests the server version.
|
/// Client requests the server version.
|
||||||
Version("VERSION"),
|
Version("VER"),
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::{Error, NutError};
|
use crate::{Error, NutError};
|
||||||
|
|
|
@ -481,7 +481,7 @@ mod tests {
|
||||||
Sentences::QueryHelp {}
|
Sentences::QueryHelp {}
|
||||||
);
|
);
|
||||||
test_encode_decode!(
|
test_encode_decode!(
|
||||||
["VERSION"] <=>
|
["VER"] <=>
|
||||||
Sentences::QueryVersion {}
|
Sentences::QueryVersion {}
|
||||||
);
|
);
|
||||||
test_encode_decode!(
|
test_encode_decode!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue