use chrono::{DateTime, Local};
use std::convert::Into;
use std::error::Error as StdError;
use std::fmt;
#[derive(Debug)]
pub enum WechatErrorKind {
Msg(String),
Io(::std::io::Error),
Custom { code: i32, msg: String },
}
#[derive(Debug)]
pub struct WechatError {
pub kind: WechatErrorKind,
pub source: Option<Box<dyn StdError>>,
}
unsafe impl Sync for WechatError {}
unsafe impl Send for WechatError {}
impl StdError for WechatError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.source.as_deref()
}
}
impl fmt::Display for WechatError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.kind {
WechatErrorKind::Msg(ref message) => write!(f, "{}", message),
WechatErrorKind::Custom { code, ref msg } => {
write!(f, "custom error code: {}, message: {}", code, msg)
}
WechatErrorKind::Io(ref e) => write!(f, "{}", e),
}
}
}
impl WechatError {
pub fn msg(value: impl ToString) -> Self {
Self {
kind: WechatErrorKind::Msg(value.to_string()),
source: None,
}
}
pub fn chain(value: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
Self {
kind: WechatErrorKind::Msg(value.to_string()),
source: Some(source.into()),
}
}
pub fn custom(code: i32, msg: impl ToString) -> Self {
Self {
kind: WechatErrorKind::Custom {
code,
msg: msg.to_string(),
},
source: None,
}
}
pub fn custom_err(code: i32, msg: impl ToString, source: impl Into<Box<dyn StdError>>) -> Self {
Self {
kind: WechatErrorKind::Custom {
code,
msg: msg.to_string(),
},
source: Some(source.into()),
}
}
pub fn write_to_file(content: String) {
use std::fs::OpenOptions;
use std::io::prelude::*;
let mut name = String::from("logs");
if let Ok(p) = std::env::current_exe() {
let s = p.file_name().unwrap().to_str().unwrap();
name = String::from(s);
}
let mut file_path = format!("log/{}.log", name);
let mut dir_path_str = "log/".to_owned();
if !cfg!(debug_assertions) {
if !file_path.starts_with('/') {
if let Ok(p) = std::env::current_exe() {
let workdir = format!("{}", p.parent().unwrap().display());
file_path = format!("{}/{}", &workdir, file_path.replace("./", ""));
dir_path_str = format!("{}/{}", &workdir, dir_path_str.replace("./", ""));
}
}
}
let dir_path = std::path::Path::new(&dir_path_str);
if !dir_path.exists() {
let _ = std::fs::create_dir_all(dir_path);
}
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.append(true)
.open(file_path);
let local: DateTime<Local> = Local::now();
let now_str = local.format("%Y-%m-%d %H:%M:%S").to_string();
match file {
Ok(mut stream) => {
stream
.write_all(format!("[{}] {}\n", now_str, content).as_bytes())
.unwrap();
}
Err(err) => {
println!("{:?}", err);
}
}
}
}
impl From<&str> for WechatError {
fn from(e: &str) -> Self {
Self::msg(e)
}
}
impl From<String> for WechatError {
fn from(e: String) -> Self {
Self::msg(e)
}
}
impl From<::std::io::Error> for WechatError {
fn from(e: ::std::io::Error) -> Self {
Self {
kind: WechatErrorKind::Io(e),
source: None,
}
}
}