Add all remaining errors

This commit is contained in:
Aram 🍐 2021-08-04 02:53:00 -04:00
parent 1842ebef15
commit 35d40d3111
2 changed files with 104 additions and 2 deletions

View file

@ -1,3 +1,4 @@
use crate::proto::ClientSentences;
use core::fmt;
use std::io;
@ -8,6 +9,48 @@ pub enum NutError {
AccessDenied,
/// Occurs when the specified UPS device does not exist.
UnknownUps,
/// The specified UPS doesn't support the variable in the request.
VarNotSupported,
/// The specified UPS doesn't support the instant command in the request.
CmdNotSupported,
/// The client sent an argument to a command which is not recognized or is otherwise invalid in this context.
InvalidArgument,
/// Server failed to deliver the instant command request to the driver. No further information is available to the client.
InstCmdFailed,
/// Server failed to deliver the set request to the driver.
SetFailed,
/// The requested variable in a SET command is not writable.
ReadOnly,
/// The requested value in a SET command is too long.
TooLong,
/// The server does not support the requested feature.
FeatureNotSupported,
/// TLS/SSL mode is already enabled on this connection, so the server can't start it again.
AlreadySslMode,
/// The server can't perform the requested command, since the driver for that UPS is not connected.
DriverNotConnected,
/// Server is connected to the driver for the UPS, but that driver isn't providing regular updates
/// or has specifically marked the data as stale.
DataStale,
/// The client already sent LOGIN for a UPS and can't do it again.
/// There is presently a limit of one LOGIN record per connection.
AlreadyLoggedIn,
/// The client sent an invalid PASSWORD - perhaps an empty one.
InvalidPassword,
/// The client already set a PASSWORD and can't set another.
AlreadySetPassword,
/// The client sent an invalid USERNAME.
InvalidUsername,
/// The client has already set a USERNAME, and can't set another.
AlreadySetUsername,
/// The requested command requires a username for authentication, but the client hasn't set one.
UsernameRequired,
/// The requested command requires a password for authentication, but the client hasn't set one.
PasswordRequired,
/// The server doesn't recognize the requested command.
UnknownCommand,
/// The value specified in the request is not valid.
InvalidValue,
/// Occurs when the response type or content wasn't expected at the current stage.
UnexpectedResponse,
/// Occurs when the response type is not recognized by the client.
@ -26,8 +69,28 @@ pub enum NutError {
impl fmt::Display for NutError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::AccessDenied => write!(f, "Authentication failed"),
Self::UnknownUps => write!(f, "Unknown UPS device name"),
Self::AccessDenied => write!(f, "Access denied"),
Self::UnknownUps => write!(f, "Unknown UPS device"),
Self::VarNotSupported => write!(f, "Variable not supported"),
Self::CmdNotSupported => write!(f, "Command not supported"),
Self::InvalidArgument => write!(f, "Invalid argument"),
Self::InstCmdFailed => write!(f, "Instant command failed"),
Self::SetFailed => write!(f, "Failed to set variable"),
Self::ReadOnly => write!(f, "Cannot set read-only variable"),
Self::TooLong => write!(f, "Value is too long"),
Self::FeatureNotSupported => write!(f, "Feature is not supported by server"),
Self::AlreadySslMode => write!(f, "Connection is already in TLS/SSL"),
Self::DriverNotConnected => write!(f, "Driver is not connected"),
Self::DataStale => write!(f, "Data is stale"),
Self::AlreadyLoggedIn => write!(f, "Connection is already authenticated"),
Self::InvalidPassword => write!(f, "Invalid password"),
Self::AlreadySetPassword => write!(f, "Password can only be set once"),
Self::InvalidUsername => write!(f, "Invalid username"),
Self::AlreadySetUsername => write!(f, "Username can only be set once"),
Self::UsernameRequired => write!(f, "Username required"),
Self::PasswordRequired => write!(f, "Password required"),
Self::UnknownCommand => write!(f, "Unknown command"),
Self::InvalidValue => write!(f, "Invalid value"),
Self::UnexpectedResponse => write!(f, "Unexpected server response content"),
Self::UnknownResponseType(ty) => write!(f, "Unknown response type: {}", ty),
Self::SslNotSupported => write!(f, "SSL not supported by server or transport"),
@ -41,6 +104,42 @@ impl fmt::Display for NutError {
}
}
impl<T: AsRef<ClientSentences>> From<T> for NutError {
fn from(sentence: T) -> Self {
if let ClientSentences::RespondErr { message, .. } = sentence.as_ref() {
match message.as_str() {
"ACCESS-DENIED" => Self::AccessDenied,
"UNKNOWN-UPS" => Self::UnknownUps,
"VAR-NOT-SUPPORTED" => Self::VarNotSupported,
"CMD-NOT-SUPPORTED" => Self::CmdNotSupported,
"INVALID-ARGUMENT" => Self::InvalidArgument,
"INSTCMD-FAILED" => Self::InstCmdFailed,
"SET-FAILED" => Self::SetFailed,
"READONLY" => Self::ReadOnly,
"TOO-LONG" => Self::TooLong,
"FEATURE-NOT-SUPPORTED" => Self::FeatureNotSupported,
"FEATURE-NOT-CONFIGURED" => Self::FeatureNotConfigured,
"ALREADY-SSL-MODE" => Self::AlreadySslMode,
"DRIVER-NOT-CONNECTED" => Self::DriverNotConnected,
"DATA-STALE" => Self::DataStale,
"ALREADY-LOGGED-IN" => Self::AlreadyLoggedIn,
"INVALID-PASSWORD" => Self::InvalidPassword,
"ALREADY-SET-PASSWORD" => Self::AlreadySetPassword,
"INVALID-USERNAME" => Self::InvalidUsername,
"ALREADY-SET-USERNAME" => Self::AlreadySetUsername,
"USERNAME-REQUIRED" => Self::UsernameRequired,
"PASSWORD-REQUIRED" => Self::PasswordRequired,
"UNKNOWN-COMMAND" => Self::UnknownCommand,
"INVALID-VALUE" => Self::InvalidValue,
_ => Self::Generic(message.to_string()),
}
} else {
// This is not supposed to happen...
panic!("Cannot convert {:?} into NutError", sentence.as_ref());
}
}
}
impl NutError {
/// Constructs a generic rups error.
pub fn generic<T: ToString>(message: T) -> Self {

View file

@ -11,6 +11,9 @@ pub mod server;
/// Utilities for encoding and decoding packets.
pub mod util;
pub use client::Sentences as ClientSentences;
pub use server::Sentences as ServerSentences;
/// Macro that implements the list of "words" in the NUT network protocol.
macro_rules! impl_words {
(