mirror of
https://github.com/aramperes/nut-rs.git
synced 2025-09-09 05:28:31 -04:00
Simplify errors
This commit is contained in:
parent
c935d88496
commit
96fbfeaeab
8 changed files with 109 additions and 135 deletions
|
@ -142,7 +142,7 @@ impl TcpConnection {
|
||||||
|
|
||||||
// Parse args by splitting whitespace, minding quotes for args with multiple words
|
// Parse args by splitting whitespace, minding quotes for args with multiple words
|
||||||
let args = shell_words::split(&raw)
|
let args = shell_words::split(&raw)
|
||||||
.map_err(|e| NutError::Generic(format!("Parsing server response failed: {}", e)))?;
|
.map_err(|e| NutError::generic(format!("Parsing server response failed: {}", e)))?;
|
||||||
|
|
||||||
Ok(args)
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
184
rups/src/cmd.rs
184
rups/src/cmd.rs
|
@ -118,23 +118,23 @@ pub enum Response {
|
||||||
impl Response {
|
impl Response {
|
||||||
pub fn from_args(mut args: Vec<String>) -> crate::Result<Response> {
|
pub fn from_args(mut args: Vec<String>) -> crate::Result<Response> {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return Err(
|
return Err(ClientError::generic(
|
||||||
NutError::Generic("Parsing server response failed: empty line".into()).into(),
|
"Parsing server response failed: empty line",
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
let cmd_name = args.remove(0);
|
let cmd_name = args.remove(0);
|
||||||
match cmd_name.as_str() {
|
match cmd_name.as_str() {
|
||||||
"OK" => Ok(Self::Ok),
|
"OK" => Ok(Self::Ok),
|
||||||
"ERR" => {
|
"ERR" => {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
Err(NutError::Generic("Unspecified server error".into()).into())
|
Err(ClientError::generic("Unspecified server error"))
|
||||||
} else {
|
} else {
|
||||||
let err_type = args.remove(0);
|
let err_type = args.remove(0);
|
||||||
match err_type.as_str() {
|
match err_type.as_str() {
|
||||||
"ACCESS-DENIED" => Err(NutError::AccessDenied.into()),
|
"ACCESS-DENIED" => Err(NutError::AccessDenied.into()),
|
||||||
"UNKNOWN-UPS" => Err(NutError::UnknownUps.into()),
|
"UNKNOWN-UPS" => Err(NutError::UnknownUps.into()),
|
||||||
"FEATURE-NOT-CONFIGURED" => Err(NutError::FeatureNotConfigured.into()),
|
"FEATURE-NOT-CONFIGURED" => Err(NutError::FeatureNotConfigured.into()),
|
||||||
_ => Err(NutError::Generic(format!(
|
_ => Err(NutError::generic(format!(
|
||||||
"Server error: {} {}",
|
"Server error: {} {}",
|
||||||
err_type,
|
err_type,
|
||||||
args.join(" ")
|
args.join(" ")
|
||||||
|
@ -145,14 +145,14 @@ impl Response {
|
||||||
}
|
}
|
||||||
"BEGIN" => {
|
"BEGIN" => {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
Err(NutError::Generic("Unspecified BEGIN type".into()).into())
|
Err(ClientError::generic("Unspecified BEGIN type"))
|
||||||
} else {
|
} else {
|
||||||
let begin_type = args.remove(0);
|
let begin_type = args.remove(0);
|
||||||
if &begin_type != "LIST" {
|
if &begin_type != "LIST" {
|
||||||
Err(
|
Err(ClientError::generic(format!(
|
||||||
NutError::Generic(format!("Unexpected BEGIN type: {}", begin_type))
|
"Unexpected BEGIN type: {}",
|
||||||
.into(),
|
begin_type
|
||||||
)
|
)))
|
||||||
} else {
|
} else {
|
||||||
let args = shell_words::join(args);
|
let args = shell_words::join(args);
|
||||||
Ok(Response::BeginList(args))
|
Ok(Response::BeginList(args))
|
||||||
|
@ -161,14 +161,14 @@ impl Response {
|
||||||
}
|
}
|
||||||
"END" => {
|
"END" => {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
Err(NutError::Generic("Unspecified END type".into()).into())
|
Err(ClientError::generic("Unspecified END type"))
|
||||||
} else {
|
} else {
|
||||||
let begin_type = args.remove(0);
|
let begin_type = args.remove(0);
|
||||||
if &begin_type != "LIST" {
|
if &begin_type != "LIST" {
|
||||||
Err(
|
Err(ClientError::generic(format!(
|
||||||
NutError::Generic(format!("Unexpected END type: {}", begin_type))
|
"Unexpected END type: {}",
|
||||||
.into(),
|
begin_type
|
||||||
)
|
)))
|
||||||
} else {
|
} else {
|
||||||
let args = shell_words::join(args);
|
let args = shell_words::join(args);
|
||||||
Ok(Response::EndList(args))
|
Ok(Response::EndList(args))
|
||||||
|
@ -177,23 +177,19 @@ impl Response {
|
||||||
}
|
}
|
||||||
"VAR" => {
|
"VAR" => {
|
||||||
let _var_device = if args.is_empty() {
|
let _var_device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified VAR device name in response".into(),
|
"Unspecified VAR device name in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let var_name = if args.is_empty() {
|
let var_name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified VAR name in response"))
|
||||||
"Unspecified VAR name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let var_value = if args.is_empty() {
|
let var_value = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified VAR value in response"))
|
||||||
"Unspecified VAR value in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -201,23 +197,19 @@ impl Response {
|
||||||
}
|
}
|
||||||
"RW" => {
|
"RW" => {
|
||||||
let _var_device = if args.is_empty() {
|
let _var_device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified RW device name in response".into(),
|
"Unspecified RW device name in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let var_name = if args.is_empty() {
|
let var_name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RW name in response"))
|
||||||
"Unspecified RW name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let var_value = if args.is_empty() {
|
let var_value = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RW value in response"))
|
||||||
"Unspecified RW value in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -225,16 +217,14 @@ impl Response {
|
||||||
}
|
}
|
||||||
"UPS" => {
|
"UPS" => {
|
||||||
let name = if args.is_empty() {
|
let name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified UPS name in response"))
|
||||||
"Unspecified UPS name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let description = if args.is_empty() {
|
let description = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified UPS description in response".into(),
|
"Unspecified UPS description in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -242,16 +232,14 @@ impl Response {
|
||||||
}
|
}
|
||||||
"CLIENT" => {
|
"CLIENT" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified CLIENT device in response".into(),
|
"Unspecified CLIENT device in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let ip_address = if args.is_empty() {
|
let ip_address = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified CLIENT IP in response"))
|
||||||
"Unspecified CLIENT IP in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -259,16 +247,12 @@ impl Response {
|
||||||
}
|
}
|
||||||
"CMD" => {
|
"CMD" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified CMD device in response"))
|
||||||
"Unspecified CMD device in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let name = if args.is_empty() {
|
let name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified CMD name in response"))
|
||||||
"Unspecified CMD name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -276,23 +260,21 @@ impl Response {
|
||||||
}
|
}
|
||||||
"CMDDESC" => {
|
"CMDDESC" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified CMDDESC device in response".into(),
|
"Unspecified CMDDESC device in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let _name = if args.is_empty() {
|
let _name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified CMDDESC name in response"))
|
||||||
"Unspecified CMDDESC name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let desc = if args.is_empty() {
|
let desc = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified CMDDESC description in response".into(),
|
"Unspecified CMDDESC description in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -300,16 +282,16 @@ impl Response {
|
||||||
}
|
}
|
||||||
"UPSDESC" => {
|
"UPSDESC" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified UPSDESC device in response".into(),
|
"Unspecified UPSDESC device in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let desc = if args.is_empty() {
|
let desc = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified UPSDESC description in response".into(),
|
"Unspecified UPSDESC description in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -317,23 +299,19 @@ impl Response {
|
||||||
}
|
}
|
||||||
"DESC" => {
|
"DESC" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified DESC device in response"))
|
||||||
"Unspecified DESC device in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let _name = if args.is_empty() {
|
let _name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified DESC name in response"))
|
||||||
"Unspecified DESC name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let desc = if args.is_empty() {
|
let desc = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified DESC description in response".into(),
|
"Unspecified DESC description in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -341,38 +319,32 @@ impl Response {
|
||||||
}
|
}
|
||||||
"NUMLOGINS" => {
|
"NUMLOGINS" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified NUMLOGINS device in response".into(),
|
"Unspecified NUMLOGINS device in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let num = if args.is_empty() {
|
let num = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic(
|
||||||
"Unspecified NUMLOGINS number in response".into(),
|
"Unspecified NUMLOGINS number in response",
|
||||||
)))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let num = num.parse::<i32>().map_err(|_| {
|
let num = num
|
||||||
ClientError::from(NutError::Generic(
|
.parse::<i32>()
|
||||||
"Invalid NUMLOGINS number in response".into(),
|
.map_err(|_| ClientError::generic("Invalid NUMLOGINS number in response"))?;
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Response::NumLogins(num))
|
Ok(Response::NumLogins(num))
|
||||||
}
|
}
|
||||||
"TYPE" => {
|
"TYPE" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified TYPE device in response"))
|
||||||
"Unspecified TYPE device in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let name = if args.is_empty() {
|
let name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified TYPE name in response"))
|
||||||
"Unspecified TYPE name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -381,30 +353,22 @@ impl Response {
|
||||||
}
|
}
|
||||||
"RANGE" => {
|
"RANGE" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RANGE device in response"))
|
||||||
"Unspecified RANGE device in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let _name = if args.is_empty() {
|
let _name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RANGE name in response"))
|
||||||
"Unspecified RANGE name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let min = if args.is_empty() {
|
let min = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RANGE min in response"))
|
||||||
"Unspecified RANGE min in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let max = if args.is_empty() {
|
let max = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified RANGE max in response"))
|
||||||
"Unspecified RANGE max in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
@ -412,23 +376,17 @@ impl Response {
|
||||||
}
|
}
|
||||||
"ENUM" => {
|
"ENUM" => {
|
||||||
let _device = if args.is_empty() {
|
let _device = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified ENUM device in response"))
|
||||||
"Unspecified ENUM device in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let _name = if args.is_empty() {
|
let _name = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified ENUM name in response"))
|
||||||
"Unspecified ENUM name in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
let val = if args.is_empty() {
|
let val = if args.is_empty() {
|
||||||
Err(ClientError::from(NutError::Generic(
|
Err(ClientError::generic("Unspecified ENUM value in response"))
|
||||||
"Unspecified ENUM value in response".into(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
Ok(args.remove(0))
|
Ok(args.remove(0))
|
||||||
}?;
|
}?;
|
||||||
|
|
|
@ -36,11 +36,18 @@ impl fmt::Display for NutError {
|
||||||
"Given hostname cannot be used for a strict SSL connection"
|
"Given hostname cannot be used for a strict SSL connection"
|
||||||
),
|
),
|
||||||
Self::FeatureNotConfigured => write!(f, "Feature not configured by server"),
|
Self::FeatureNotConfigured => write!(f, "Feature not configured by server"),
|
||||||
Self::Generic(msg) => write!(f, "Internal client error: {}", msg),
|
Self::Generic(msg) => write!(f, "Client error: {}", msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NutError {
|
||||||
|
/// Constructs a generic rups error.
|
||||||
|
pub fn generic<T: ToString>(message: T) -> Self {
|
||||||
|
Self::Generic(message.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::error::Error for NutError {}
|
impl std::error::Error for NutError {}
|
||||||
|
|
||||||
/// Encapsulation for errors emitted by the client library.
|
/// Encapsulation for errors emitted by the client library.
|
||||||
|
@ -52,6 +59,13 @@ pub enum ClientError {
|
||||||
Nut(NutError),
|
Nut(NutError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ClientError {
|
||||||
|
/// 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 ClientError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use error::*;
|
pub use error::*;
|
||||||
|
pub use util::*;
|
||||||
pub use var::*;
|
pub use var::*;
|
||||||
|
|
||||||
/// Blocking client implementation for NUT.
|
/// Blocking client implementation for NUT.
|
||||||
|
@ -20,4 +21,5 @@ mod config;
|
||||||
mod error;
|
mod error;
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
mod ssl;
|
mod ssl;
|
||||||
|
mod util;
|
||||||
mod var;
|
mod var;
|
||||||
|
|
|
@ -148,7 +148,7 @@ impl TcpConnection {
|
||||||
|
|
||||||
// Parse args by splitting whitespace, minding quotes for args with multiple words
|
// Parse args by splitting whitespace, minding quotes for args with multiple words
|
||||||
let args = shell_words::split(&raw)
|
let args = shell_words::split(&raw)
|
||||||
.map_err(|e| NutError::Generic(format!("Parsing server response failed: {}", e)))?;
|
.map_err(|e| NutError::generic(format!("Parsing server response failed: {}", e)))?;
|
||||||
|
|
||||||
Ok(args)
|
Ok(args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
use anyhow::Context;
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
/// The default upsd hostname.
|
||||||
pub const DEFAULT_HOSTNAME: &str = "localhost";
|
pub const DEFAULT_HOSTNAME: &str = "localhost";
|
||||||
|
/// The default upsd port.
|
||||||
pub const DEFAULT_PORT: u16 = 3493;
|
pub const DEFAULT_PORT: u16 = 3493;
|
||||||
|
|
||||||
/// Connection information for a upsd server.
|
/// TCP connection information for a upsd server.
|
||||||
///
|
///
|
||||||
/// The upsname is optional depending on context.
|
/// The upsname is optional depending on context.
|
||||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
pub struct UpsdName<'a> {
|
pub struct UpsdName<'a> {
|
||||||
|
/// The name of the ups device, if specified.
|
||||||
pub upsname: Option<&'a str>,
|
pub upsname: Option<&'a str>,
|
||||||
|
/// The hostname of the upsd server.
|
||||||
pub hostname: &'a str,
|
pub hostname: &'a str,
|
||||||
|
/// The port of the upsd server.
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,9 +30,9 @@ impl<'a> Default for UpsdName<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a str> for UpsdName<'a> {
|
impl<'a> TryFrom<&'a str> for UpsdName<'a> {
|
||||||
type Error = anyhow::Error;
|
type Error = crate::ClientError;
|
||||||
|
|
||||||
fn try_from(value: &'a str) -> anyhow::Result<UpsdName<'a>> {
|
fn try_from(value: &'a str) -> crate::Result<UpsdName<'a>> {
|
||||||
let mut upsname: Option<&str> = None;
|
let mut upsname: Option<&str> = None;
|
||||||
let mut hostname = DEFAULT_HOSTNAME;
|
let mut hostname = DEFAULT_HOSTNAME;
|
||||||
let mut port = DEFAULT_PORT;
|
let mut port = DEFAULT_PORT;
|
||||||
|
@ -40,7 +44,7 @@ impl<'a> TryFrom<&'a str> for UpsdName<'a> {
|
||||||
.next()
|
.next()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.parse::<u16>()
|
.parse::<u16>()
|
||||||
.with_context(|| "invalid port number")?;
|
.map_err(|_| crate::ClientError::generic("Invalid port number"))?;
|
||||||
if prefix.contains('@') {
|
if prefix.contains('@') {
|
||||||
let mut split = prefix.splitn(2, '@');
|
let mut split = prefix.splitn(2, '@');
|
||||||
upsname = Some(split.next().unwrap());
|
upsname = Some(split.next().unwrap());
|
||||||
|
@ -64,13 +68,13 @@ impl<'a> TryFrom<&'a str> for UpsdName<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryInto<rups::Host> for UpsdName<'a> {
|
impl<'a> TryInto<crate::Host> for UpsdName<'a> {
|
||||||
type Error = anyhow::Error;
|
type Error = crate::ClientError;
|
||||||
|
|
||||||
fn try_into(self) -> anyhow::Result<rups::Host> {
|
fn try_into(self) -> crate::Result<crate::Host> {
|
||||||
(self.hostname.to_owned(), self.port)
|
(self.hostname.to_owned(), self.port)
|
||||||
.try_into()
|
.try_into()
|
||||||
.with_context(|| "Invalid hostname/port")
|
.map_err(|_| crate::ClientError::generic("Invalid hostname/port"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,17 +200,13 @@ impl TryFrom<&str> for VariableType {
|
||||||
.nth(1)
|
.nth(1)
|
||||||
.map(|s| s.parse().ok())
|
.map(|s| s.parse().ok())
|
||||||
.flatten()
|
.flatten()
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| crate::ClientError::generic("Invalid STRING definition"))?;
|
||||||
crate::ClientError::Nut(crate::NutError::Generic(
|
|
||||||
"Invalid STRING definition".into(),
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
Ok(Self::String(size))
|
Ok(Self::String(size))
|
||||||
} else {
|
} else {
|
||||||
Err(crate::ClientError::Nut(crate::NutError::Generic(format!(
|
Err(crate::ClientError::generic(format!(
|
||||||
"Unrecognized variable type: {}",
|
"Unrecognized variable type: {}",
|
||||||
value
|
value
|
||||||
))))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ use core::convert::TryInto;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clap::{App, Arg};
|
use clap::{App, Arg};
|
||||||
|
|
||||||
use crate::parser::UpsdName;
|
use rups::UpsdName;
|
||||||
|
|
||||||
mod cmd;
|
mod cmd;
|
||||||
mod parser;
|
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let args = App::new(clap::crate_name!())
|
let args = App::new(clap::crate_name!())
|
||||||
|
@ -72,7 +72,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
)
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
let server: parser::UpsdName = args.value_of("upsd-server").map_or_else(
|
let server: UpsdName = args.value_of("upsd-server").map_or_else(
|
||||||
|| Ok(UpsdName::default()),
|
|| Ok(UpsdName::default()),
|
||||||
|s| s.try_into().with_context(|| "Invalid upsd server name"),
|
|s| s.try_into().with_context(|| "Invalid upsd server name"),
|
||||||
)?;
|
)?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue