mirror of
https://github.com/arampoire/nut-rs.git
synced 2025-12-01 00:30:23 -05: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
|
|
@ -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