chimes_utils/wechat/
errors.rs

1//! copyright © ecdata.cn 2020 - present
2//! 自定义错误信息处理
3//! created by shaipe
4
5use chrono::{DateTime, Local};
6use std::convert::Into;
7use std::error::Error as StdError;
8use std::fmt;
9
10#[derive(Debug)]
11pub enum WechatErrorKind {
12    Msg(String),
13    Io(::std::io::Error),
14    Custom { code: i32, msg: String },
15}
16
17/// The WechatError type
18#[derive(Debug)]
19pub struct WechatError {
20    /// Kind of error
21    pub kind: WechatErrorKind,
22    pub source: Option<Box<dyn StdError>>,
23}
24unsafe impl Sync for WechatError {}
25unsafe impl Send for WechatError {}
26
27/// 继承标准接口
28impl StdError for WechatError {
29    fn source(&self) -> Option<&(dyn StdError + 'static)> {
30        self.source.as_deref()
31    }
32}
33
34/// 格式化显示设置
35impl fmt::Display for WechatError {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        match self.kind {
38            WechatErrorKind::Msg(ref message) => write!(f, "{}", message),
39            WechatErrorKind::Custom { code, ref msg } => {
40                write!(f, "custom error code: {}, message: {}", code, msg)
41            }
42            WechatErrorKind::Io(ref e) => write!(f, "{}", e),
43        }
44    }
45}
46
47impl WechatError {
48    /// Creates generic error
49    pub fn msg(value: impl ToString) -> Self {
50        Self {
51            kind: WechatErrorKind::Msg(value.to_string()),
52            source: None,
53        }
54    }
55
56    /// Creates generic error with a cause
57    pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
58        Self {
59            kind: WechatErrorKind::Msg(value.to_string()),
60            source: Some(source.into()),
61        }
62    }
63
64    /// 自定义错误
65    pub fn custom(code: i32, msg: impl ToString) -> Self {
66        Self {
67            kind: WechatErrorKind::Custom {
68                code,
69                msg: msg.to_string(),
70            },
71            source: None,
72        }
73    }
74
75    /// 自定义错误
76    pub fn custom_err(code: i32, msg: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
77        Self {
78            kind: WechatErrorKind::Custom {
79                code,
80                msg: msg.to_string(),
81            },
82            source: Some(source.into()),
83        }
84    }
85
86    /// 写入文件到日志
87    // #[allow(dead_code)]
88    pub fn write_to_file(content: String) {
89        use std::fs::OpenOptions;
90        use std::io::prelude::*;
91        let mut name = String::from("logs");
92        // 获取当前应用名称
93        if let Ok(p) = std::env::current_exe() {
94            let s = p.file_name().unwrap().to_str().unwrap();
95            name = String::from(s);
96        }
97
98        let mut file_path = format!("log/{}.log", name);
99        let mut dir_path_str = "log/".to_owned();
100        // 只有非调试模式下才使用下面的配置
101        if !cfg!(debug_assertions) {
102            // 给定了相对顶层路径时不处理
103            if !file_path.starts_with('/') {
104                if let Ok(p) = std::env::current_exe() {
105                    let workdir = format!("{}", p.parent().unwrap().display());
106                    file_path = format!("{}/{}", &workdir, file_path.replace("./", ""));
107                    dir_path_str = format!("{}/{}", &workdir, dir_path_str.replace("./", ""));
108                }
109            }
110        }
111
112        let dir_path = std::path::Path::new(&dir_path_str);
113        if !dir_path.exists() {
114            let _ = std::fs::create_dir_all(dir_path);
115        }
116        // println!("sdsdds{}", file_path);
117        // 以读,写,创建,追加的方式打开文件
118        let file = OpenOptions::new()
119            .read(true)
120            .write(true)
121            .create(true)
122            .append(true)
123            .open(file_path);
124
125        let local: DateTime<Local> = Local::now();
126        let now_str = local.format("%Y-%m-%d %H:%M:%S").to_string();
127
128        // 向文件中写入内容
129        match file {
130            Ok(mut stream) => {
131                stream
132                    .write_all(format!("[{}] {}\n", now_str, content).as_bytes())
133                    .unwrap();
134            }
135            Err(err) => {
136                println!("{:?}", err);
137            }
138        }
139    }
140}
141
142impl From<&str> for WechatError {
143    fn from(e: &str) -> Self {
144        Self::msg(e)
145    }
146}
147impl From<String> for WechatError {
148    fn from(e: String) -> Self {
149        Self::msg(e)
150    }
151}
152impl From<::std::io::Error> for WechatError {
153    fn from(e: ::std::io::Error) -> Self {
154        Self {
155            kind: WechatErrorKind::Io(e),
156            source: None,
157        }
158    }
159}