1use std::fmt::Display;
2use std::path::{Path, StripPrefixError};
3use std::{io, num};
4use thiserror::Error;
5
6pub type MyResult<T> = Result<T, MyError>;
7
8#[derive(Debug, Error)]
9pub enum MyError {
10 #[error(transparent)]
11 Chrono(#[from] chrono::ParseError),
12 #[error(transparent)]
13 Clap(#[from] clap::error::Error),
14 #[error(transparent)]
15 Git(#[from] git2::Error),
16 #[error("{0}: {1}")]
17 Glob(glob::PatternError, String),
18 #[error(transparent)]
19 Io(#[from] io::Error),
20 #[error("{0}: {1}")]
21 Io2(io::Error, String),
22 #[error(transparent)]
23 ParseInt(#[from] num::ParseIntError),
24 #[error("{0}: {1}")]
25 PkZip(zip::result::ZipError, String),
26 #[error("{0}: {1}")]
27 Prefix(StripPrefixError, String),
28 #[error(transparent)]
29 Regex(#[from] regex::Error),
30 #[error("{0}: {1}")]
31 SevenZ(sevenz_rust2::Error, String),
32 #[error(transparent)]
33 Walk(#[from] walkdir::Error),
34 #[error("{0}")]
35 Text(String),
36}
37
38impl MyError {
39 pub fn create_clap<T: Display>(option: &str, value: T) -> Self {
40 let message = format!("Invalid {option} option: {value}");
41 let error = clap::Error::raw(clap::error::ErrorKind::ValueValidation, message);
42 Self::Clap(error)
43 }
44
45 pub fn print_error(&self) {
46 if let Some(help) = self.get_help() {
47 let help = help.trim_end();
48 println!("{help}");
49 } else {
50 let error = self.to_string();
51 let error = error.trim_end();
52 eprintln!("{error}");
53 }
54 }
55
56 fn get_help(&self) -> Option<String> {
57 if let Self::Clap(err) = self {
58 match err.kind() {
59 clap::error::ErrorKind::DisplayHelp => Some(err.to_string()),
60 clap::error::ErrorKind::DisplayVersion => Some(err.to_string()),
61 _ => None,
62 }
63 } else {
64 None
65 }
66 }
67}
68
69impl From<(glob::PatternError, &String)> for MyError {
70 fn from(value: (glob::PatternError, &String)) -> Self {
71 let (error, glob) = value;
72 let glob = glob.to_string();
73 Self::Glob(error, glob)
74 }
75}
76
77impl From<(io::Error, &Path)> for MyError {
78 fn from(value: (io::Error, &Path)) -> Self {
79 let (error, path) = value;
80 let path = path.display().to_string();
81 Self::Io2(error, path)
82 }
83}
84
85impl From<(zip::result::ZipError, &Path)> for MyError {
86 fn from(value: (zip::result::ZipError, &Path)) -> Self {
87 let (error, path) = value;
88 let path = path.display().to_string();
89 Self::PkZip(error, path)
90 }
91}
92
93impl From<(StripPrefixError, &Path)> for MyError {
94 fn from(value: (StripPrefixError, &Path)) -> Self {
95 let (error, path) = value;
96 let path = path.display().to_string();
97 Self::Prefix(error, path)
98 }
99}
100
101impl From<(sevenz_rust2::Error, &Path)> for MyError {
102 fn from(value: (sevenz_rust2::Error, &Path)) -> Self {
103 let (error, path) = value;
104 let path = path.display().to_string();
105 Self::SevenZ(error, path)
106 }
107}
108
109impl From<&str> for MyError {
110 fn from(error: &str) -> Self {
111 let error = error.to_string();
112 Self::Text(error)
113 }
114}