diff --git a/nut-client/src/blocking/mod.rs b/nut-client/src/blocking/mod.rs index 11286f2..3fd810c 100644 --- a/nut-client/src/blocking/mod.rs +++ b/nut-client/src/blocking/mod.rs @@ -94,7 +94,8 @@ impl TcpConnection { self.stream = self.stream.upgrade_ssl(sess)?; // Send a test command - self.get_network_version()?; + self.write_cmd(Command::NetworkVersion)?; + self.read_plain_response()?; } Ok(self) } @@ -119,12 +120,6 @@ impl TcpConnection { Ok(()) } - #[allow(dead_code)] - fn get_network_version(&mut self) -> crate::Result { - self.write_cmd(Command::NetworkVersion)?; - self.read_plain_response() - } - pub(crate) fn write_cmd(&mut self, line: Command) -> crate::Result<()> { let line = format!("{}\n", line); if self.config.debug { diff --git a/nut-client/src/cmd.rs b/nut-client/src/cmd.rs index 1f8aff3..1295254 100644 --- a/nut-client/src/cmd.rs +++ b/nut-client/src/cmd.rs @@ -337,6 +337,54 @@ macro_rules! implement_get_commands { }; } +/// A macro for implementing simple/direct commands. +/// +/// Each function should return a 2-tuple with +/// (1) the command to pass +/// (2) a closure for mapping the `String` row to the return type +macro_rules! implement_simple_commands { + ( + $( + $(#[$attr:meta])+ + fn $name:ident($($argname:ident: $argty:ty),*) -> $retty:ty { + ( + $cmd: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($cmd)?; + ($mapper)(conn.read_plain_response()?) + }, + } + } + )* + } + + #[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($cmd).await?; + ($mapper)(conn.read_plain_response().await?) + }, + } + } + )* + } + }; +} + implement_list_commands! { /// Queries a list of UPS devices. fn list_ups() -> Vec<(String, String)> { @@ -372,3 +420,13 @@ implement_get_commands! { ) } } + +implement_simple_commands! { + /// Queries the network protocol version. + fn get_network_version() -> String { + ( + { Command::NetworkVersion }, + { |row: String| Ok(row) }, + ) + } +} diff --git a/nut-client/src/tokio/mod.rs b/nut-client/src/tokio/mod.rs index 6e1e563..b8269e7 100644 --- a/nut-client/src/tokio/mod.rs +++ b/nut-client/src/tokio/mod.rs @@ -101,7 +101,8 @@ impl TcpConnection { self.stream = self.stream.upgrade_ssl(config, dns_name.as_ref()).await?; // Send a test command - self.get_network_version().await?; + self.write_cmd(Command::NetworkVersion).await?; + self.read_plain_response().await?; } Ok(self) } @@ -126,12 +127,6 @@ impl TcpConnection { Ok(()) } - #[allow(dead_code)] - async fn get_network_version(&mut self) -> crate::Result { - self.write_cmd(Command::NetworkVersion).await?; - self.read_plain_response().await - } - pub(crate) async fn write_cmd(&mut self, line: Command<'_>) -> crate::Result<()> { let line = format!("{}\n", line); if self.config.debug {