Use thiserror to format error messages

This commit is contained in:
veeso
2021-04-03 16:33:18 +02:00
parent af678802bb
commit 91081cb86a
4 changed files with 31 additions and 41 deletions

View File

@@ -13,7 +13,6 @@ readme = "README.md"
repository = "https://github.com/veeso/termscp" repository = "https://github.com/veeso/termscp"
version = "0.4.1" version = "0.4.1"
[metadata]
[metadata.rpm] [metadata.rpm]
package = "termscp" package = "termscp"
@@ -23,6 +22,7 @@ buildflags = ["--release"]
[metadata.rpm.targets] [metadata.rpm.targets]
[metadata.rpm.targets.termscp] [metadata.rpm.targets.termscp]
path = "/usr/bin/termscp" path = "/usr/bin/termscp"
[[bin]] [[bin]]
name = "termscp" name = "termscp"
path = "src/main.rs" path = "src/main.rs"
@@ -70,7 +70,6 @@ version = "2.0.2"
[features] [features]
githubActions = [] githubActions = []
[target]
[target."cfg(any(target_os = \"unix\", target_os = \"macos\", target_os = \"linux\"))"] [target."cfg(any(target_os = \"unix\", target_os = \"macos\", target_os = \"linux\"))"]
[target."cfg(any(target_os = \"unix\", target_os = \"macos\", target_os = \"linux\"))".dependencies] [target."cfg(any(target_os = \"unix\", target_os = \"macos\", target_os = \"linux\"))".dependencies]
users = "0.11.0" users = "0.11.0"

View File

@@ -29,6 +29,7 @@ pub mod serializer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use thiserror::Error;
#[derive(Deserialize, Serialize, std::fmt::Debug)] #[derive(Deserialize, Serialize, std::fmt::Debug)]
/// ## UserHosts /// ## UserHosts
@@ -66,10 +67,13 @@ pub struct SerializerError {
/// ## SerializerErrorKind /// ## SerializerErrorKind
/// ///
/// Describes the kind of error for the serializer/deserializer /// Describes the kind of error for the serializer/deserializer
#[derive(std::fmt::Debug, PartialEq)] #[derive(Error, Debug)]
pub enum SerializerErrorKind { pub enum SerializerErrorKind {
#[error("IO error")]
IoError, IoError,
#[error("Serialization error")]
SerializationError, SerializationError,
#[error("Syntax error")]
SyntaxError, SyntaxError,
} }
@@ -102,14 +106,9 @@ impl SerializerError {
impl std::fmt::Display for SerializerError { impl std::fmt::Display for SerializerError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let err: String = match &self.kind {
SerializerErrorKind::IoError => String::from("IO error"),
SerializerErrorKind::SerializationError => String::from("Serialization error"),
SerializerErrorKind::SyntaxError => String::from("Syntax error"),
};
match &self.msg { match &self.msg {
Some(msg) => write!(f, "{} ({})", err, msg), Some(msg) => write!(f, "{} ({})", self.kind, msg),
None => write!(f, "{}", err), None => write!(f, "{}", self.kind),
} }
} }
} }
@@ -172,12 +171,10 @@ mod tests {
#[test] #[test]
fn test_bookmarks_bookmark_errors() { fn test_bookmarks_bookmark_errors() {
let error: SerializerError = SerializerError::new(SerializerErrorKind::SyntaxError); let error: SerializerError = SerializerError::new(SerializerErrorKind::SyntaxError);
assert_eq!(error.kind, SerializerErrorKind::SyntaxError);
assert!(error.msg.is_none()); assert!(error.msg.is_none());
assert_eq!(format!("{}", error), String::from("Syntax error")); assert_eq!(format!("{}", error), String::from("Syntax error"));
let error: SerializerError = let error: SerializerError =
SerializerError::new_ex(SerializerErrorKind::SyntaxError, String::from("bad syntax")); SerializerError::new_ex(SerializerErrorKind::SyntaxError, String::from("bad syntax"));
assert_eq!(error.kind, SerializerErrorKind::SyntaxError);
assert!(error.msg.is_some()); assert!(error.msg.is_some());
assert_eq!( assert_eq!(
format!("{}", error), format!("{}", error),

View File

@@ -38,6 +38,7 @@ use crate::filetransfer::FileTransferProtocol;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashMap; use std::collections::HashMap;
use std::path::PathBuf; use std::path::PathBuf;
use thiserror::Error;
#[derive(Deserialize, Serialize, std::fmt::Debug)] #[derive(Deserialize, Serialize, std::fmt::Debug)]
/// ## UserConfig /// ## UserConfig
@@ -117,10 +118,13 @@ pub struct SerializerError {
/// ## SerializerErrorKind /// ## SerializerErrorKind
/// ///
/// Describes the kind of error for the serializer/deserializer /// Describes the kind of error for the serializer/deserializer
#[derive(std::fmt::Debug, PartialEq)] #[derive(Error, Debug)]
pub enum SerializerErrorKind { pub enum SerializerErrorKind {
#[error("IO error")]
IoError, IoError,
#[error("Serialization error")]
SerializationError, SerializationError,
#[error("Syntax error")]
SyntaxError, SyntaxError,
} }
@@ -144,14 +148,9 @@ impl SerializerError {
impl std::fmt::Display for SerializerError { impl std::fmt::Display for SerializerError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let err: String = match &self.kind {
SerializerErrorKind::IoError => String::from("IO error"),
SerializerErrorKind::SerializationError => String::from("Serialization error"),
SerializerErrorKind::SyntaxError => String::from("Syntax error"),
};
match &self.msg { match &self.msg {
Some(msg) => write!(f, "{} ({})", err, msg), Some(msg) => write!(f, "{} ({})", self.kind, msg),
None => write!(f, "{}", err), None => write!(f, "{}", self.kind),
} }
} }
} }
@@ -214,12 +213,10 @@ mod tests {
#[test] #[test]
fn test_config_mod_errors() { fn test_config_mod_errors() {
let error: SerializerError = SerializerError::new(SerializerErrorKind::SyntaxError); let error: SerializerError = SerializerError::new(SerializerErrorKind::SyntaxError);
assert_eq!(error.kind, SerializerErrorKind::SyntaxError);
assert!(error.msg.is_none()); assert!(error.msg.is_none());
assert_eq!(format!("{}", error), String::from("Syntax error")); assert_eq!(format!("{}", error), String::from("Syntax error"));
let error: SerializerError = let error: SerializerError =
SerializerError::new_ex(SerializerErrorKind::SyntaxError, String::from("bad syntax")); SerializerError::new_ex(SerializerErrorKind::SyntaxError, String::from("bad syntax"));
assert_eq!(error.kind, SerializerErrorKind::SyntaxError);
assert!(error.msg.is_some()); assert!(error.msg.is_some());
assert_eq!( assert_eq!(
format!("{}", error), format!("{}", error),

View File

@@ -32,6 +32,7 @@ use crate::fs::{FsEntry, FsFile};
// ext // ext
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use thiserror::Error;
use wildmatch::WildMatch; use wildmatch::WildMatch;
// exports // exports
pub mod ftp_transfer; pub mod ftp_transfer;
@@ -62,19 +63,31 @@ pub struct FileTransferError {
/// ///
/// FileTransferErrorType defines the possible errors available for a file transfer /// FileTransferErrorType defines the possible errors available for a file transfer
#[allow(dead_code)] #[allow(dead_code)]
#[derive(std::fmt::Debug)] #[derive(Error, Debug)]
pub enum FileTransferErrorType { pub enum FileTransferErrorType {
#[error("Authentication failed")]
AuthenticationFailed, AuthenticationFailed,
#[error("Bad address syntax")]
BadAddress, BadAddress,
#[error("Connection error")]
ConnectionError, ConnectionError,
#[error("SSL error")]
SslError, SslError,
#[error("Could not stat directory")]
DirStatFailed, DirStatFailed,
#[error("Failed to create file")]
FileCreateDenied, FileCreateDenied,
#[error("IO error: {0}")]
IoErr(std::io::Error), IoErr(std::io::Error),
#[error("No such file or directory")]
NoSuchFileOrDirectory, NoSuchFileOrDirectory,
#[error("Not enough permissions")]
PexError, PexError,
#[error("Protocol error")]
ProtocolError, ProtocolError,
#[error("Uninitialized session")]
UninitializedSession, UninitializedSession,
#[error("Unsupported feature")]
UnsupportedFeature, UnsupportedFeature,
} }
@@ -98,25 +111,9 @@ impl FileTransferError {
impl std::fmt::Display for FileTransferError { impl std::fmt::Display for FileTransferError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let err: String = match &self.code {
FileTransferErrorType::AuthenticationFailed => String::from("Authentication failed"),
FileTransferErrorType::BadAddress => String::from("Bad address syntax"),
FileTransferErrorType::ConnectionError => String::from("Connection error"),
FileTransferErrorType::DirStatFailed => String::from("Could not stat directory"),
FileTransferErrorType::FileCreateDenied => String::from("Failed to create file"),
FileTransferErrorType::IoErr(err) => format!("IO error: {}", err),
FileTransferErrorType::NoSuchFileOrDirectory => {
String::from("No such file or directory")
}
FileTransferErrorType::PexError => String::from("Not enough permissions"),
FileTransferErrorType::ProtocolError => String::from("Protocol error"),
FileTransferErrorType::SslError => String::from("SSL error"),
FileTransferErrorType::UninitializedSession => String::from("Uninitialized session"),
FileTransferErrorType::UnsupportedFeature => String::from("Unsupported feature"),
};
match &self.msg { match &self.msg {
Some(msg) => write!(f, "{} ({})", err, msg), Some(msg) => write!(f, "{} ({})", self.code, msg),
None => write!(f, "{}", err), None => write!(f, "{}", self.code),
} }
} }
} }