mirror of
https://github.com/arampoire/nut-rs.git
synced 2025-12-01 00:30:23 -05:00
Generify LIST commands in blocking/tokio
This commit is contained in:
parent
65f25fb958
commit
bab1264364
5 changed files with 83 additions and 106 deletions
|
|
@ -28,7 +28,7 @@ async = ["tokio"]
|
|||
async-ssl = ["async", "tokio-rustls", "ssl"]
|
||||
|
||||
# a feature gate for examples
|
||||
async-rt = ["tokio/rt-multi-thread", "tokio/macros"]
|
||||
async-rt = ["async", "tokio/rt-multi-thread", "tokio/macros"]
|
||||
|
||||
[[example]]
|
||||
name = "async"
|
||||
|
|
|
|||
|
|
@ -21,31 +21,6 @@ impl Connection {
|
|||
}
|
||||
}
|
||||
|
||||
/// Queries a list of UPS devices.
|
||||
pub fn list_ups(&mut self) -> crate::Result<Vec<(String, String)>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => conn.list_ups(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries a list of client IP addresses connected to the given device.
|
||||
pub fn list_clients(&mut self, ups_name: &str) -> crate::Result<Vec<String>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => conn.list_clients(ups_name),
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries the list of variables for a UPS device.
|
||||
pub fn list_vars(&mut self, ups_name: &str) -> crate::Result<Vec<Variable>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => Ok(conn
|
||||
.list_vars(ups_name)?
|
||||
.into_iter()
|
||||
.map(|(key, val)| Variable::parse(key.as_str(), val))
|
||||
.collect()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries one variable for a UPS device.
|
||||
pub fn get_var(&mut self, ups_name: &str, variable: &str) -> crate::Result<Variable> {
|
||||
match self {
|
||||
|
|
@ -154,30 +129,6 @@ impl TcpConnection {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn list_ups(&mut self) -> crate::Result<Vec<(String, String)>> {
|
||||
let query = &["UPS"];
|
||||
self.write_cmd(Command::List(query))?;
|
||||
|
||||
let list = self.read_list(query)?;
|
||||
list.into_iter().map(|row| row.expect_ups()).collect()
|
||||
}
|
||||
|
||||
fn list_clients(&mut self, ups_name: &str) -> crate::Result<Vec<String>> {
|
||||
let query = &["CLIENT", ups_name];
|
||||
self.write_cmd(Command::List(query))?;
|
||||
|
||||
let list = self.read_list(query)?;
|
||||
list.into_iter().map(|row| row.expect_client()).collect()
|
||||
}
|
||||
|
||||
fn list_vars(&mut self, ups_name: &str) -> crate::Result<Vec<(String, String)>> {
|
||||
let query = &["VAR", ups_name];
|
||||
self.write_cmd(Command::List(query))?;
|
||||
|
||||
let list = self.read_list(query)?;
|
||||
list.into_iter().map(|row| row.expect_var()).collect()
|
||||
}
|
||||
|
||||
fn get_var(&mut self, ups_name: &str, variable: &str) -> crate::Result<(String, String)> {
|
||||
let query = &["VAR", ups_name, variable];
|
||||
self.write_cmd(Command::Get(query))?;
|
||||
|
|
@ -191,7 +142,7 @@ impl TcpConnection {
|
|||
self.read_plain_response()
|
||||
}
|
||||
|
||||
fn write_cmd(&mut self, line: Command) -> crate::Result<()> {
|
||||
pub(crate) fn write_cmd(&mut self, line: Command) -> crate::Result<()> {
|
||||
let line = format!("{}\n", line);
|
||||
if self.config.debug {
|
||||
eprint!("DEBUG -> {}", line);
|
||||
|
|
@ -231,7 +182,7 @@ impl TcpConnection {
|
|||
Ok(args.join(" "))
|
||||
}
|
||||
|
||||
fn read_list(&mut self, query: &[&str]) -> crate::Result<Vec<Response>> {
|
||||
pub(crate) fn read_list(&mut self, query: &[&str]) -> crate::Result<Vec<Response>> {
|
||||
let mut reader = BufReader::new(&mut self.stream);
|
||||
let args = Self::parse_line(&mut reader, self.config.debug)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use core::fmt;
|
||||
|
||||
use crate::{ClientError, NutError};
|
||||
use crate::{ClientError, NutError, Variable};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Command<'a> {
|
||||
|
|
@ -238,3 +238,79 @@ impl Response {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro for implementing `LIST` commands.
|
||||
///
|
||||
/// Each function should return a 2-tuple with
|
||||
/// (1) the query to pass to `LIST`
|
||||
/// (2) a closure for mapping each `Response` row to the return type
|
||||
macro_rules! implement_list_commands {
|
||||
(
|
||||
$(
|
||||
$(#[$attr:meta])+
|
||||
fn $name:ident($($argname:ident: $argty:ty),*) -> $retty:ty {
|
||||
(
|
||||
$query:block,
|
||||
$mapper:block,
|
||||
)
|
||||
}
|
||||
)*
|
||||
) => {
|
||||
impl crate::blocking::Connection {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
pub fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<$retty> {
|
||||
match self {
|
||||
Self::Tcp(conn) => {
|
||||
conn.write_cmd(Command::List($query))?;
|
||||
let list = conn.read_list($query)?;
|
||||
list.into_iter().map($mapper).collect()
|
||||
},
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
|
||||
#[cfg(feature = "async")]
|
||||
impl crate::tokio::Connection {
|
||||
$(
|
||||
$(#[$attr])*
|
||||
pub async fn $name(&mut self$(, $argname: $argty)*) -> crate::Result<$retty> {
|
||||
match self {
|
||||
Self::Tcp(conn) => {
|
||||
conn.write_cmd(Command::List($query)).await?;
|
||||
let list = conn.read_list($query).await?;
|
||||
list.into_iter().map($mapper).collect()
|
||||
},
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
implement_list_commands! {
|
||||
/// Queries a list of UPS devices.
|
||||
fn list_ups() -> Vec<(String, String)> {
|
||||
(
|
||||
{ &["UPS"] },
|
||||
{ |row| row.expect_ups() },
|
||||
)
|
||||
}
|
||||
|
||||
/// Queries a list of client IP addresses connected to the given device.
|
||||
fn list_clients(ups_name: &str) -> Vec<String> {
|
||||
(
|
||||
{ &["CLIENT", ups_name] },
|
||||
{ |row| row.expect_client() },
|
||||
)
|
||||
}
|
||||
|
||||
/// Queries the list of variables for a UPS device.
|
||||
fn list_vars(ups_name: &str) -> Vec<Variable> {
|
||||
(
|
||||
{ &["VAR", ups_name] },
|
||||
{ |row| row.expect_var().map(|var| Variable::parse(var.0.as_str(), var.1)) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub use var::*;
|
|||
/// Blocking client implementation for NUT.
|
||||
pub mod blocking;
|
||||
/// Async client implementation for NUT, using Tokio.
|
||||
#[cfg(feature = "tokio")]
|
||||
#[cfg(feature = "async")]
|
||||
pub mod tokio;
|
||||
|
||||
mod cmd;
|
||||
|
|
|
|||
|
|
@ -24,32 +24,6 @@ impl Connection {
|
|||
}
|
||||
}
|
||||
|
||||
/// Queries a list of UPS devices.
|
||||
pub async fn list_ups(&mut self) -> crate::Result<Vec<(String, String)>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => conn.list_ups().await,
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries a list of client IP addresses connected to the given device.
|
||||
pub async fn list_clients(&mut self, ups_name: &str) -> crate::Result<Vec<String>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => conn.list_clients(ups_name).await,
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries the list of variables for a UPS device.
|
||||
pub async fn list_vars(&mut self, ups_name: &str) -> crate::Result<Vec<Variable>> {
|
||||
match self {
|
||||
Self::Tcp(conn) => Ok(conn
|
||||
.list_vars(ups_name)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|(key, val)| Variable::parse(key.as_str(), val))
|
||||
.collect()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries one variable for a UPS device.
|
||||
pub async fn get_var(&mut self, ups_name: &str, variable: &str) -> crate::Result<Variable> {
|
||||
match self {
|
||||
|
|
@ -162,30 +136,6 @@ impl TcpConnection {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn list_ups(&mut self) -> crate::Result<Vec<(String, String)>> {
|
||||
let query = &["UPS"];
|
||||
self.write_cmd(Command::List(query)).await?;
|
||||
|
||||
let list = self.read_list(query).await?;
|
||||
list.into_iter().map(|row| row.expect_ups()).collect()
|
||||
}
|
||||
|
||||
async fn list_clients(&mut self, ups_name: &str) -> crate::Result<Vec<String>> {
|
||||
let query = &["CLIENT", ups_name];
|
||||
self.write_cmd(Command::List(query)).await?;
|
||||
|
||||
let list = self.read_list(query).await?;
|
||||
list.into_iter().map(|row| row.expect_client()).collect()
|
||||
}
|
||||
|
||||
async fn list_vars(&mut self, ups_name: &str) -> crate::Result<Vec<(String, String)>> {
|
||||
let query = &["VAR", ups_name];
|
||||
self.write_cmd(Command::List(query)).await?;
|
||||
|
||||
let list = self.read_list(query).await?;
|
||||
list.into_iter().map(|row| row.expect_var()).collect()
|
||||
}
|
||||
|
||||
async fn get_var<'a>(
|
||||
&mut self,
|
||||
ups_name: &'a str,
|
||||
|
|
@ -203,7 +153,7 @@ impl TcpConnection {
|
|||
self.read_plain_response().await
|
||||
}
|
||||
|
||||
async fn write_cmd(&mut self, line: Command<'_>) -> crate::Result<()> {
|
||||
pub(crate) async fn write_cmd(&mut self, line: Command<'_>) -> crate::Result<()> {
|
||||
let line = format!("{}\n", line);
|
||||
if self.config.debug {
|
||||
eprint!("DEBUG -> {}", line);
|
||||
|
|
@ -243,7 +193,7 @@ impl TcpConnection {
|
|||
Ok(args.join(" "))
|
||||
}
|
||||
|
||||
async fn read_list(&mut self, query: &[&str]) -> crate::Result<Vec<Response>> {
|
||||
pub(crate) async fn read_list(&mut self, query: &[&str]) -> crate::Result<Vec<Response>> {
|
||||
let mut reader = BufReader::new(&mut self.stream);
|
||||
let args = Self::parse_line(&mut reader, self.config.debug).await?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue