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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! Errors in leetcode-cli
use crate::cmds::{Command, DataCommand};
use colored::Colorize;
use std::fmt;

/// Error enum
#[derive(Clone)]
pub enum Error {
    MatchError,
    DownloadError(String),
    NetworkError(String),
    ParseError(String),
    CacheError(String),
    FeatureError(String),
    ScriptError(String),
    CookieError,
    DecryptError,
    SilentError,
}

impl std::fmt::Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let e = "error:".bold().red();
        match self {
            Error::CacheError(s) => write!(f, "{} {}, please try again", e, s),
            Error::CookieError => write!(
                f,
                "{} {}{}{}{}{}",
                e,
                "Your leetcode cookies seems expired, ",
                "please make sure you have logined in leetcode.com with chrome. "
                    .yellow()
                    .bold(),
                "Either you can handwrite your `LEETCODE_SESSION` and `csrf` into `leetcode.toml`, ",
                "more info please checkout this: ",
                "https://github.com/clearloop/leetcode-cli/blob/master/README.md#cookies"
            ),
            Error::DownloadError(s) => write!(f, "{} Download {} failed, please try again", e, s),
            Error::NetworkError(s) => write!(f, "{} {}, please try again", e, s),
            Error::ParseError(s) => write!(f, "{} {}", e, s),
            Error::FeatureError(s) => write!(f, "{} {}", e, s),
            Error::MatchError => write!(f, "{} Nothing matches", e),
            Error::DecryptError => write!(f, "{} openssl decrypt failed", e),
            Error::ScriptError(s) => write!(f, "{} {}", e, s),
            Error::SilentError => write!(f, ""),
        }
    }
}

// network
impl std::convert::From<reqwest::Error> for Error {
    fn from(err: reqwest::Error) -> Self {
        Error::NetworkError(err.to_string())
    }
}

// nums
impl std::convert::From<std::num::ParseIntError> for Error {
    fn from(err: std::num::ParseIntError) -> Self {
        Error::ParseError(err.to_string())
    }
}

// sql
impl std::convert::From<diesel::result::Error> for Error {
    fn from(err: diesel::result::Error) -> Self {
        match err {
            diesel::result::Error::NotFound => {
                println!("NotFound, you may update cache, and try it again\r\n");
                DataCommand::usage().print_help().unwrap_or(());
                Error::SilentError
            }
            _ => Error::CacheError(err.to_string()),
        }
    }
}

// serde
impl std::convert::From<serde_json::error::Error> for Error {
    fn from(err: serde_json::Error) -> Self {
        Error::ParseError(err.to_string())
    }
}

// toml
impl std::convert::From<toml::de::Error> for Error {
    fn from(err: toml::de::Error) -> Self {
        Error::ParseError(format!(
            "{}, {}{}{}{}{}{}{}{}",
            err.to_string(),
            "Parse config file failed, ",
            "leetcode-cli has just generated a new leetcode.toml at ",
            "~/.leetcode/leetcode_tmp.toml,".green().bold().underline(),
            " the current one at ",
            "~/.leetcode/leetcode.toml".yellow().bold().underline(),
            "seems missing some keys, please compare to ",
            "the tmp one and add them up : )\n",
            ".",
        ))
    }
}

impl std::convert::From<toml::ser::Error> for Error {
    fn from(err: toml::ser::Error) -> Self {
        Error::ParseError(err.to_string())
    }
}

// io
impl std::convert::From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Self {
        Error::CacheError(err.to_string())
    }
}

// options
impl std::convert::From<std::option::NoneError> for Error {
    fn from(_: std::option::NoneError) -> Self {
        Error::ParseError(format!(
            "{}{}{}{}",
            "json from response parse failed, ",
            "please open a new issue at: ",
            "https://github.com/clearloop/leetcode-cli/".underline(),
            "."
        ))
    }
}

// openssl
impl std::convert::From<openssl::error::ErrorStack> for Error {
    fn from(_: openssl::error::ErrorStack) -> Self {
        Error::DecryptError
    }
}

// pyo3
#[cfg(feature = "pym")]
impl std::convert::From<pyo3::PyErr> for Error {
    fn from(_: pyo3::PyErr) -> Self {
        Error::ScriptError("Python script went Error".to_string())
    }
}