Start work on generic protocol impl for #28

This commit is contained in:
Aram 🍐 2021-08-03 02:40:54 -04:00
parent ff77c1bdbd
commit 2224c1dd6b
2 changed files with 114 additions and 0 deletions

View file

@ -19,6 +19,8 @@ pub mod tokio;
mod cmd; mod cmd;
mod config; mod config;
mod error; mod error;
/// Bi-directional networking protocol implementation.
mod proto;
#[cfg(feature = "ssl")] #[cfg(feature = "ssl")]
mod ssl; mod ssl;
mod util; mod util;

112
rups/src/proto/mod.rs Normal file
View file

@ -0,0 +1,112 @@
///! NUT protocol implementation (v1.2).
///! Documentation: https://networkupstools.org/docs/developer-guide.chunked/ar01s09.html
macro_rules! impl_words {
(
$(
$(#[$attr:meta])+
$name:ident($word:tt),
)*
) => {
pub(crate) enum Word {
/// A string argument.
Arg,
/// End-of-line.
EOL,
$(
/// Protocol word.
$(#[$attr])*
#[allow(dead_code)]
$name,
)*
}
impl Word {
/// Matches a raw string into the corresponding word.
/// Passing `None` will always return `EOL`. Passing an unrecognized
/// string returns `None`.
pub(crate) fn decode(raw: Option<&str>) -> Option<Self> {
if let Some(raw) = raw {
match raw {
$($word => Some(Self::$name),)*
_ => None
}
} else {
Some(Self::EOL)
}
}
/// Encodes a `Word` into a string.
/// This function cannot encode `Arg` or `EOL` (either returns `None`).
pub(crate) fn encode(&self) -> Option<&str> {
match self {
Self::Arg | Self::EOL => None,
$(Self::$name => Some($word),)*
}
}
}
};
}
impl_words! {
/// Begins a `LIST`.
Begin("BEGIN"),
/// Describes a client connected to a UPS.
Client("CLIENT"),
/// Represents an executable command.
Cmd("CMD"),
/// Describes a command (`CMD`).
CmdDesc("CMDDESC"),
/// Describes a variable (`VAR` or `RW`).
Desc("DESC"),
/// Ends a block of sentences.
End("END"),
/// An enumerable type.
Enum("ENUM"),
/// An error response.
Err("ERR"),
/// Executes a forced shut down (FSD).
Fsd("FSD"),
/// Serverbound query.
Get("GET"),
/// Client requesting a list of commands supported by the server.
Help("HELP"),
/// Executes an instant command.
InstCmd("INSTCMD"),
/// Queries or describes a list.
List("LIST"),
/// Client requests login to a UPS device.
Login("LOGIN"),
/// Client logs out.
Logout("LOGOUT"),
/// Client verifying it has master-level access to the UPS device.
Master("MASTER"),
/// Client requests the network version.
NetworkVersion("NETVER"),
/// Represents the amount of logins to a UPS device.
NumLogins("NUMLOGINS"),
/// Clientbound response for a good outcome.
Ok("OK"),
/// Client setting password.
Password("PASSWORD"),
/// Represents a range of numerical values.
Range("RANGE"),
/// Represents a mutable variable.
Rw("RW"),
/// Client requests to set the value of a mutable variable.
Set("SET"),
/// Client requests the connection be upgraded to TLS.
StartTLS("STARTTLS"),
/// Represents the type of a variable.
Type("TYPE"),
/// Represents a UPS device.
Ups("UPS"),
/// Represents the description of a UPS device.
UpsDesc("UPSDESC"),
/// Client setting username.
Username("USERNAME"),
/// Represents a variable.
Var("VAR"),
/// Client requests the server version.
Version("VERSION"),
}