Skip to content

Commit 2224c1d

Browse files
committed
Start work on generic protocol impl for #28
1 parent ff77c1b commit 2224c1d

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

rups/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub mod tokio;
1919
mod cmd;
2020
mod config;
2121
mod error;
22+
/// Bi-directional networking protocol implementation.
23+
mod proto;
2224
#[cfg(feature = "ssl")]
2325
mod ssl;
2426
mod util;

rups/src/proto/mod.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
///! NUT protocol implementation (v1.2).
2+
///! Documentation: https://networkupstools.org/docs/developer-guide.chunked/ar01s09.html
3+
4+
macro_rules! impl_words {
5+
(
6+
$(
7+
$(#[$attr:meta])+
8+
$name:ident($word:tt),
9+
)*
10+
) => {
11+
pub(crate) enum Word {
12+
/// A string argument.
13+
Arg,
14+
/// End-of-line.
15+
EOL,
16+
$(
17+
/// Protocol word.
18+
$(#[$attr])*
19+
#[allow(dead_code)]
20+
$name,
21+
)*
22+
}
23+
24+
impl Word {
25+
/// Matches a raw string into the corresponding word.
26+
/// Passing `None` will always return `EOL`. Passing an unrecognized
27+
/// string returns `None`.
28+
pub(crate) fn decode(raw: Option<&str>) -> Option<Self> {
29+
if let Some(raw) = raw {
30+
match raw {
31+
$($word => Some(Self::$name),)*
32+
_ => None
33+
}
34+
} else {
35+
Some(Self::EOL)
36+
}
37+
}
38+
39+
/// Encodes a `Word` into a string.
40+
/// This function cannot encode `Arg` or `EOL` (either returns `None`).
41+
pub(crate) fn encode(&self) -> Option<&str> {
42+
match self {
43+
Self::Arg | Self::EOL => None,
44+
$(Self::$name => Some($word),)*
45+
}
46+
}
47+
}
48+
};
49+
}
50+
51+
impl_words! {
52+
/// Begins a `LIST`.
53+
Begin("BEGIN"),
54+
/// Describes a client connected to a UPS.
55+
Client("CLIENT"),
56+
/// Represents an executable command.
57+
Cmd("CMD"),
58+
/// Describes a command (`CMD`).
59+
CmdDesc("CMDDESC"),
60+
/// Describes a variable (`VAR` or `RW`).
61+
Desc("DESC"),
62+
/// Ends a block of sentences.
63+
End("END"),
64+
/// An enumerable type.
65+
Enum("ENUM"),
66+
/// An error response.
67+
Err("ERR"),
68+
/// Executes a forced shut down (FSD).
69+
Fsd("FSD"),
70+
/// Serverbound query.
71+
Get("GET"),
72+
/// Client requesting a list of commands supported by the server.
73+
Help("HELP"),
74+
/// Executes an instant command.
75+
InstCmd("INSTCMD"),
76+
/// Queries or describes a list.
77+
List("LIST"),
78+
/// Client requests login to a UPS device.
79+
Login("LOGIN"),
80+
/// Client logs out.
81+
Logout("LOGOUT"),
82+
/// Client verifying it has master-level access to the UPS device.
83+
Master("MASTER"),
84+
/// Client requests the network version.
85+
NetworkVersion("NETVER"),
86+
/// Represents the amount of logins to a UPS device.
87+
NumLogins("NUMLOGINS"),
88+
/// Clientbound response for a good outcome.
89+
Ok("OK"),
90+
/// Client setting password.
91+
Password("PASSWORD"),
92+
/// Represents a range of numerical values.
93+
Range("RANGE"),
94+
/// Represents a mutable variable.
95+
Rw("RW"),
96+
/// Client requests to set the value of a mutable variable.
97+
Set("SET"),
98+
/// Client requests the connection be upgraded to TLS.
99+
StartTLS("STARTTLS"),
100+
/// Represents the type of a variable.
101+
Type("TYPE"),
102+
/// Represents a UPS device.
103+
Ups("UPS"),
104+
/// Represents the description of a UPS device.
105+
UpsDesc("UPSDESC"),
106+
/// Client setting username.
107+
Username("USERNAME"),
108+
/// Represents a variable.
109+
Var("VAR"),
110+
/// Client requests the server version.
111+
Version("VERSION"),
112+
}

0 commit comments

Comments
 (0)