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
//! Errors in leetcode-cli
use colored::Colorize;
use std::error::Error as StdError;
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,
}

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,
                "Cannot get leetcode cookies from chrome, ",
                "please make sure you have logined in leetcode.com with chrome. "
                    .yellow()
                    .bold(),
                "Either you can handwrite your LEETCODE_SESSION and csrf to 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),
        }
    }
}

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

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

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

// serde
impl std::convert::From<serde_json::error::Error> for Error {
    fn from(err: serde_json::Error) -> Self {
        error!("{:?}", &err);
        Error::ParseError(err.description().to_string())
    }
}

// toml
impl std::convert::From<toml::de::Error> for Error {
    fn from(err: toml::de::Error) -> Self {
        Error::ParseError(format!(
            "{}, {}{}{}{}{}{}{}{}",
            err.description().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.description().to_string())
    }
}

// io
impl std::convert::From<std::io::Error> for Error {
    fn from(err: std::io::Error) -> Self {
        Error::CacheError(err.description().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
impl std::convert::From<pyo3::PyErr> for Error {
    fn from(_: pyo3::PyErr) -> Self {
        Error::ScriptError("Python script went Error".to_string())
    }
}