Rename ClientError to Error

This commit is contained in:
Aram 🍐 2021-08-04 15:14:23 -04:00
parent 7d26301571
commit ea96f433e6
8 changed files with 86 additions and 107 deletions

View file

@ -3,7 +3,7 @@ use std::net::{SocketAddr, TcpStream};
use crate::blocking::stream::ConnectionStream;
use crate::cmd::{Command, Response};
use crate::{ClientError, Config, Host, NutError};
use crate::{Config, Error, Host, NutError};
mod stream;
@ -71,8 +71,8 @@ impl TcpConnection {
self.write_cmd(Command::StartTLS)?;
self.read_response()
.map_err(|e| {
if let crate::ClientError::Nut(NutError::FeatureNotConfigured) = e {
crate::ClientError::Nut(NutError::SslNotSupported)
if let Error::Nut(NutError::FeatureNotConfigured) = e {
Error::Nut(NutError::SslNotSupported)
} else {
e
}
@ -96,10 +96,10 @@ impl TcpConnection {
.config
.host
.hostname()
.ok_or(ClientError::Nut(NutError::SslInvalidHostname))?;
.ok_or(Error::Nut(NutError::SslInvalidHostname))?;
let dns_name = webpki::DNSNameRef::try_from_ascii_str(&hostname)
.map_err(|_| ClientError::Nut(NutError::SslInvalidHostname))?;
.map_err(|_| Error::Nut(NutError::SslInvalidHostname))?;
ssl_config
.root_store

View file

@ -1,7 +1,7 @@
use core::fmt;
use std::convert::TryFrom;
use crate::{ClientError, NutError, Variable, VariableDefinition, VariableRange};
use crate::{Error, NutError, Variable, VariableDefinition, VariableRange};
#[derive(Debug, Clone)]
pub enum Command<'a> {
@ -118,16 +118,14 @@ pub enum Response {
impl Response {
pub(crate) fn from_args(mut args: Vec<String>) -> crate::Result<Response> {
if args.is_empty() {
return Err(ClientError::generic(
"Parsing server response failed: empty line",
));
return Err(Error::generic("Parsing server response failed: empty line"));
}
let cmd_name = args.remove(0);
match cmd_name.as_str() {
"OK" => Ok(Self::Ok),
"ERR" => {
if args.is_empty() {
Err(ClientError::generic("Unspecified server error"))
Err(Error::generic("Unspecified server error"))
} else {
let err_type = args.remove(0);
match err_type.as_str() {
@ -145,11 +143,11 @@ impl Response {
}
"BEGIN" => {
if args.is_empty() {
Err(ClientError::generic("Unspecified BEGIN type"))
Err(Error::generic("Unspecified BEGIN type"))
} else {
let begin_type = args.remove(0);
if &begin_type != "LIST" {
Err(ClientError::generic(format!(
Err(Error::generic(format!(
"Unexpected BEGIN type: {}",
begin_type
)))
@ -161,11 +159,11 @@ impl Response {
}
"END" => {
if args.is_empty() {
Err(ClientError::generic("Unspecified END type"))
Err(Error::generic("Unspecified END type"))
} else {
let begin_type = args.remove(0);
if &begin_type != "LIST" {
Err(ClientError::generic(format!(
Err(Error::generic(format!(
"Unexpected END type: {}",
begin_type
)))
@ -177,19 +175,17 @@ impl Response {
}
"VAR" => {
let _var_device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified VAR device name in response",
))
Err(Error::generic("Unspecified VAR device name in response"))
} else {
Ok(args.remove(0))
}?;
let var_name = if args.is_empty() {
Err(ClientError::generic("Unspecified VAR name in response"))
Err(Error::generic("Unspecified VAR name in response"))
} else {
Ok(args.remove(0))
}?;
let var_value = if args.is_empty() {
Err(ClientError::generic("Unspecified VAR value in response"))
Err(Error::generic("Unspecified VAR value in response"))
} else {
Ok(args.remove(0))
}?;
@ -197,19 +193,17 @@ impl Response {
}
"RW" => {
let _var_device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified RW device name in response",
))
Err(Error::generic("Unspecified RW device name in response"))
} else {
Ok(args.remove(0))
}?;
let var_name = if args.is_empty() {
Err(ClientError::generic("Unspecified RW name in response"))
Err(Error::generic("Unspecified RW name in response"))
} else {
Ok(args.remove(0))
}?;
let var_value = if args.is_empty() {
Err(ClientError::generic("Unspecified RW value in response"))
Err(Error::generic("Unspecified RW value in response"))
} else {
Ok(args.remove(0))
}?;
@ -217,14 +211,12 @@ impl Response {
}
"UPS" => {
let name = if args.is_empty() {
Err(ClientError::generic("Unspecified UPS name in response"))
Err(Error::generic("Unspecified UPS name in response"))
} else {
Ok(args.remove(0))
}?;
let description = if args.is_empty() {
Err(ClientError::generic(
"Unspecified UPS description in response",
))
Err(Error::generic("Unspecified UPS description in response"))
} else {
Ok(args.remove(0))
}?;
@ -232,14 +224,12 @@ impl Response {
}
"CLIENT" => {
let _device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified CLIENT device in response",
))
Err(Error::generic("Unspecified CLIENT device in response"))
} else {
Ok(args.remove(0))
}?;
let ip_address = if args.is_empty() {
Err(ClientError::generic("Unspecified CLIENT IP in response"))
Err(Error::generic("Unspecified CLIENT IP in response"))
} else {
Ok(args.remove(0))
}?;
@ -247,12 +237,12 @@ impl Response {
}
"CMD" => {
let _device = if args.is_empty() {
Err(ClientError::generic("Unspecified CMD device in response"))
Err(Error::generic("Unspecified CMD device in response"))
} else {
Ok(args.remove(0))
}?;
let name = if args.is_empty() {
Err(ClientError::generic("Unspecified CMD name in response"))
Err(Error::generic("Unspecified CMD name in response"))
} else {
Ok(args.remove(0))
}?;
@ -260,19 +250,17 @@ impl Response {
}
"CMDDESC" => {
let _device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified CMDDESC device in response",
))
Err(Error::generic("Unspecified CMDDESC device in response"))
} else {
Ok(args.remove(0))
}?;
let _name = if args.is_empty() {
Err(ClientError::generic("Unspecified CMDDESC name in response"))
Err(Error::generic("Unspecified CMDDESC name in response"))
} else {
Ok(args.remove(0))
}?;
let desc = if args.is_empty() {
Err(ClientError::generic(
Err(Error::generic(
"Unspecified CMDDESC description in response",
))
} else {
@ -282,14 +270,12 @@ impl Response {
}
"UPSDESC" => {
let _device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified UPSDESC device in response",
))
Err(Error::generic("Unspecified UPSDESC device in response"))
} else {
Ok(args.remove(0))
}?;
let desc = if args.is_empty() {
Err(ClientError::generic(
Err(Error::generic(
"Unspecified UPSDESC description in response",
))
} else {
@ -299,19 +285,17 @@ impl Response {
}
"DESC" => {
let _device = if args.is_empty() {
Err(ClientError::generic("Unspecified DESC device in response"))
Err(Error::generic("Unspecified DESC device in response"))
} else {
Ok(args.remove(0))
}?;
let _name = if args.is_empty() {
Err(ClientError::generic("Unspecified DESC name in response"))
Err(Error::generic("Unspecified DESC name in response"))
} else {
Ok(args.remove(0))
}?;
let desc = if args.is_empty() {
Err(ClientError::generic(
"Unspecified DESC description in response",
))
Err(Error::generic("Unspecified DESC description in response"))
} else {
Ok(args.remove(0))
}?;
@ -319,32 +303,28 @@ impl Response {
}
"NUMLOGINS" => {
let _device = if args.is_empty() {
Err(ClientError::generic(
"Unspecified NUMLOGINS device in response",
))
Err(Error::generic("Unspecified NUMLOGINS device in response"))
} else {
Ok(args.remove(0))
}?;
let num = if args.is_empty() {
Err(ClientError::generic(
"Unspecified NUMLOGINS number in response",
))
Err(Error::generic("Unspecified NUMLOGINS number in response"))
} else {
Ok(args.remove(0))
}?;
let num = num
.parse::<i32>()
.map_err(|_| ClientError::generic("Invalid NUMLOGINS number in response"))?;
.map_err(|_| Error::generic("Invalid NUMLOGINS number in response"))?;
Ok(Response::NumLogins(num))
}
"TYPE" => {
let _device = if args.is_empty() {
Err(ClientError::generic("Unspecified TYPE device in response"))
Err(Error::generic("Unspecified TYPE device in response"))
} else {
Ok(args.remove(0))
}?;
let name = if args.is_empty() {
Err(ClientError::generic("Unspecified TYPE name in response"))
Err(Error::generic("Unspecified TYPE name in response"))
} else {
Ok(args.remove(0))
}?;
@ -353,22 +333,22 @@ impl Response {
}
"RANGE" => {
let _device = if args.is_empty() {
Err(ClientError::generic("Unspecified RANGE device in response"))
Err(Error::generic("Unspecified RANGE device in response"))
} else {
Ok(args.remove(0))
}?;
let _name = if args.is_empty() {
Err(ClientError::generic("Unspecified RANGE name in response"))
Err(Error::generic("Unspecified RANGE name in response"))
} else {
Ok(args.remove(0))
}?;
let min = if args.is_empty() {
Err(ClientError::generic("Unspecified RANGE min in response"))
Err(Error::generic("Unspecified RANGE min in response"))
} else {
Ok(args.remove(0))
}?;
let max = if args.is_empty() {
Err(ClientError::generic("Unspecified RANGE max in response"))
Err(Error::generic("Unspecified RANGE max in response"))
} else {
Ok(args.remove(0))
}?;
@ -376,17 +356,17 @@ impl Response {
}
"ENUM" => {
let _device = if args.is_empty() {
Err(ClientError::generic("Unspecified ENUM device in response"))
Err(Error::generic("Unspecified ENUM device in response"))
} else {
Ok(args.remove(0))
}?;
let _name = if args.is_empty() {
Err(ClientError::generic("Unspecified ENUM name in response"))
Err(Error::generic("Unspecified ENUM name in response"))
} else {
Ok(args.remove(0))
}?;
let val = if args.is_empty() {
Err(ClientError::generic("Unspecified ENUM value in response"))
Err(Error::generic("Unspecified ENUM value in response"))
} else {
Ok(args.remove(0))
}?;

View file

@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto};
use std::net::{SocketAddr, ToSocketAddrs};
use std::time::Duration;
use crate::ClientError;
use crate::Error;
/// A host specification.
#[derive(Clone, Debug)]
@ -46,16 +46,16 @@ pub struct TcpHost {
}
impl TryFrom<(String, u16)> for Host {
type Error = ClientError;
type Error = Error;
fn try_from(hostname_port: (String, u16)) -> Result<Self, Self::Error> {
let (hostname, _) = hostname_port.clone();
let addr = hostname_port
.to_socket_addrs()
.map_err(ClientError::Io)?
.map_err(Error::Io)?
.next()
.ok_or_else(|| {
ClientError::Io(std::io::Error::new(
Error::Io(std::io::Error::new(
std::io::ErrorKind::AddrNotAvailable,
"no address given",
))

View file

@ -99,7 +99,7 @@ impl fmt::Display for NutError {
"Given hostname cannot be used for a strict SSL connection"
),
Self::FeatureNotConfigured => write!(f, "Feature not configured by server"),
Self::Generic(msg) => write!(f, "Client error: {}", msg),
Self::Generic(msg) => write!(f, "NUT error: {}", msg),
}
}
}
@ -149,23 +149,23 @@ impl NutError {
impl std::error::Error for NutError {}
/// Encapsulation for errors emitted by the client library.
/// Encapsulation for errors emitted by the `rups` library.
#[derive(Debug)]
pub enum ClientError {
pub enum Error {
/// Encapsulates IO errors.
Io(io::Error),
/// Encapsulates NUT and client-specific errors.
/// Encapsulates NUT errors.
Nut(NutError),
}
impl ClientError {
impl Error {
/// Constructs a generic rups error.
pub fn generic<T: ToString>(message: T) -> Self {
NutError::generic(message.to_string()).into()
}
}
impl fmt::Display for ClientError {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(err) => err.fmt(f),
@ -174,19 +174,19 @@ impl fmt::Display for ClientError {
}
}
impl std::error::Error for ClientError {}
impl std::error::Error for Error {}
impl From<io::Error> for ClientError {
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
ClientError::Io(err)
Error::Io(err)
}
}
impl From<NutError> for ClientError {
impl From<NutError> for Error {
fn from(err: NutError) -> Self {
ClientError::Nut(err)
Error::Nut(err)
}
}
/// Result type for [`ClientError`]
pub type Result<T> = std::result::Result<T, ClientError>;
/// Result type for [`Error`]
pub type Result<T> = std::result::Result<T, Error>;

View file

@ -2,7 +2,7 @@ use std::net::SocketAddr;
use crate::cmd::{Command, Response};
use crate::tokio::stream::ConnectionStream;
use crate::{Config, Host, NutError};
use crate::{Config, Error, Host, NutError};
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::net::TcpStream;
@ -74,8 +74,8 @@ impl TcpConnection {
self.read_response()
.await
.map_err(|e| {
if let crate::ClientError::Nut(NutError::FeatureNotConfigured) = e {
crate::ClientError::Nut(NutError::SslNotSupported)
if let Error::Nut(NutError::FeatureNotConfigured) = e {
Error::Nut(NutError::SslNotSupported)
} else {
e
}
@ -101,10 +101,10 @@ impl TcpConnection {
.config
.host
.hostname()
.ok_or(crate::ClientError::Nut(NutError::SslInvalidHostname))?;
.ok_or(Error::Nut(NutError::SslInvalidHostname))?;
dns_name = webpki::DNSNameRef::try_from_ascii_str(&hostname)
.map_err(|_| crate::ClientError::Nut(NutError::SslInvalidHostname))?
.map_err(|_| Error::Nut(NutError::SslInvalidHostname))?
.to_owned();
ssl_config
@ -115,7 +115,10 @@ impl TcpConnection {
let config = tokio_rustls::TlsConnector::from(std::sync::Arc::new(ssl_config));
// Wrap and override the TCP stream
self.stream = self.stream.upgrade_ssl_client(config, dns_name.as_ref()).await?;
self.stream = self
.stream
.upgrade_ssl_client(config, dns_name.as_ref())
.await?;
}
Ok(self)
}

View file

@ -1,4 +1,4 @@
use std::io::Error;
use crate::Error;
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
@ -27,10 +27,7 @@ impl ConnectionStream {
dns_name: webpki::DNSNameRef<'_>,
) -> crate::Result<ConnectionStream> {
Ok(ConnectionStream::SslClient(Box::new(
config
.connect(dns_name, self)
.await
.map_err(crate::ClientError::Io)?,
config.connect(dns_name, self).await.map_err(Error::Io)?,
)))
}
@ -41,10 +38,7 @@ impl ConnectionStream {
acceptor: tokio_rustls::TlsAcceptor,
) -> crate::Result<ConnectionStream> {
Ok(ConnectionStream::SslServer(Box::new(
acceptor
.accept(self)
.await
.map_err(crate::ClientError::Io)?,
acceptor.accept(self).await.map_err(Error::Io)?,
)))
}
}
@ -79,7 +73,7 @@ impl AsyncWrite for ConnectionStream {
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, Error>> {
) -> Poll<std::io::Result<usize>> {
match self.get_mut() {
Self::Plain(stream) => {
let pinned = Pin::new(stream);
@ -98,7 +92,7 @@ impl AsyncWrite for ConnectionStream {
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
match self.get_mut() {
Self::Plain(stream) => {
let pinned = Pin::new(stream);
@ -117,7 +111,7 @@ impl AsyncWrite for ConnectionStream {
}
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
match self.get_mut() {
Self::Plain(stream) => {
let pinned = Pin::new(stream);

View file

@ -1,3 +1,4 @@
use crate::Error;
use std::convert::{TryFrom, TryInto};
use std::fmt;
@ -30,7 +31,7 @@ impl<'a> Default for UpsdName<'a> {
}
impl<'a> TryFrom<&'a str> for UpsdName<'a> {
type Error = crate::ClientError;
type Error = crate::Error;
fn try_from(value: &'a str) -> crate::Result<UpsdName<'a>> {
let mut upsname: Option<&str> = None;
@ -44,7 +45,7 @@ impl<'a> TryFrom<&'a str> for UpsdName<'a> {
.next()
.unwrap()
.parse::<u16>()
.map_err(|_| crate::ClientError::generic("Invalid port number"))?;
.map_err(|_| Error::generic("Invalid port number"))?;
if prefix.contains('@') {
let mut split = prefix.splitn(2, '@');
upsname = Some(split.next().unwrap());
@ -69,12 +70,12 @@ impl<'a> TryFrom<&'a str> for UpsdName<'a> {
}
impl<'a> TryInto<crate::Host> for UpsdName<'a> {
type Error = crate::ClientError;
type Error = crate::Error;
fn try_into(self) -> crate::Result<crate::Host> {
(self.hostname.to_owned(), self.port)
.try_into()
.map_err(|_| crate::ClientError::generic("Invalid hostname/port"))
.map_err(|_| Error::generic("Invalid hostname/port"))
}
}

View file

@ -1,3 +1,4 @@
use crate::Error;
use core::fmt;
use std::collections::HashSet;
use std::convert::TryFrom;
@ -185,7 +186,7 @@ pub(crate) enum VariableType {
}
impl TryFrom<&str> for VariableType {
type Error = crate::ClientError;
type Error = crate::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
@ -200,10 +201,10 @@ impl TryFrom<&str> for VariableType {
.nth(1)
.map(|s| s.parse().ok())
.flatten()
.ok_or_else(|| crate::ClientError::generic("Invalid STRING definition"))?;
.ok_or_else(|| Error::generic("Invalid STRING definition"))?;
Ok(Self::String(size))
} else {
Err(crate::ClientError::generic(format!(
Err(Error::generic(format!(
"Unrecognized variable type: {}",
value
)))
@ -259,7 +260,7 @@ impl VariableDefinition {
}
impl<A: ToString> TryFrom<(A, Vec<&str>)> for VariableDefinition {
type Error = crate::ClientError;
type Error = crate::Error;
fn try_from(value: (A, Vec<&str>)) -> Result<Self, Self::Error> {
Ok(VariableDefinition(