easy_err/
err.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use std::{error, fmt, fs, io::{self, Write}, path::Path};

use colored::Colorize;


/// 用于统一错误的枚举
/// 
/// # Examples
/// ``` 
/// let err = err::Error::custom("Here is a error.");
/// err.report();
/// ```
#[derive(Debug)]
pub enum Error {
	/// 用于包装已经实现Error Trait的结构体或枚举
	Basic(Box<dyn error::Error>),
	/// 用于报告用户自定义的错误信息
	Custom(String)
}

impl Error {
	/// 产生一个basic变体
	/// 
	/// # Examples
	/// ```
	/// let file = std::fs::File::open("An obvious mistake.").or_else(|err|{Err(crate::err::Error::basic(Box::new(err)))});
	/// match file {
	/// 	Ok(_) => println!("Ok!"),
	/// 	Err(err) => {err.report().panic();}
	/// }
	/// ```
	pub fn basic(err: Box<dyn error::Error>) -> Error {
		Error::Basic(err)
	}

	/// 产生一个custom变体
	/// 
	/// # Examples
	/// ```
	/// let custom_err = err::Error::custom("Here is a error.");
	/// custom_err.report();
	/// ```
	pub fn custom<S>(msg: S) -> Error where S:ToString{
		Error::Custom(msg.to_string())
	}

	/// 在标准错误流中输出一条报告信息
	/// 
	/// # Examples
	/// ```
	/// let custom_err = err::Error::custom("Here is a error.");
	/// custom_err.report(); // error: Here is a error.
	/// ```
	pub fn report(&self) -> &Self {
		eprintln!("{}", self);
		self
	}

	/// 引发 panic!() 宏
	/// 
	/// # Examples
	/// ```
	/// let custom_err = err::Error::custom("Here is a error.");
	/// custom_err.panic(); // error: Here is a error.
	/// ```
	pub fn panic(&self){
		panic!("{}", self);
	}

	/// 将报告信息输出至文件
	/// 
	/// # Params
	/// - path: 任何可以转换为 Path 的值
	/// 
	/// # Examples
	/// ```
	/// let custom_err = err::Error::custom("Here is a error.");
	/// custom_err.log_to("./log.txt").unwrap();
	/// ```
	pub fn log_to<P>(&self, path: P) -> Result<&Self, Error> where P: AsRef<Path> {
		let mut file = fs::File::create(path)?;
		file.write(self.to_string().as_bytes())?;
		Ok(self)
	}
}

impl From<io::Error> for Error {
	fn from(value: io::Error) -> Self {
		Error::Basic(Box::new(value))
	}
}

impl fmt::Display for Error {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		match self {
			Self::Basic(err) => write!(f, "{}: {}", "error".red().bold(), err),
			Self::Custom(msg) => write!(f, "{}: {}", "error".red().bold(), msg)
		}
	}
}

impl error::Error for Error {
	fn source(&self) -> Option<&(dyn error::Error + 'static)> {
		match self {
			Self::Basic(err) => Some(err.as_ref()),
			Self::Custom(_) => None
		}
	}
}