From 35d40d31116b745967927fbc944a18232dbf8fb1 Mon Sep 17 00:00:00 2001 From: Aram Peres Date: Wed, 4 Aug 2021 02:53:00 -0400 Subject: [PATCH] Add all remaining errors --- rups/src/error.rs | 103 +++++++++++++++++++++++++++++++++++++++++- rups/src/proto/mod.rs | 3 ++ 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/rups/src/error.rs b/rups/src/error.rs index 53d7ac9..66df1c5 100644 --- a/rups/src/error.rs +++ b/rups/src/error.rs @@ -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> From 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(message: T) -> Self { diff --git a/rups/src/proto/mod.rs b/rups/src/proto/mod.rs index 15a7509..a1d5c6e 100644 --- a/rups/src/proto/mod.rs +++ b/rups/src/proto/mod.rs @@ -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 { (