1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2pub enum Fault {
3 NoKey,
4 Refused,
5 Forbidden,
6 Unreachable,
7 BadAnswer,
8 RateLimited,
9}
10
11impl Fault {
12 pub const ALL: [Fault; 6] = [
13 Fault::NoKey,
14 Fault::Refused,
15 Fault::Forbidden,
16 Fault::Unreachable,
17 Fault::BadAnswer,
18 Fault::RateLimited,
19 ];
20
21 pub fn parse(error: &str) -> Option<(Fault, &str)> {
22 let (word, message) = error.split_once(": ")?;
23 let fault = Fault::ALL.into_iter().find(|f| f.word() == word)?;
24 Some((fault, message))
25 }
26
27 pub fn word(self) -> &'static str {
28 match self {
29 Fault::NoKey => "no_key",
30 Fault::Refused => "refused",
31 Fault::Forbidden => "forbidden",
32 Fault::Unreachable => "unreachable",
33 Fault::BadAnswer => "bad_answer",
34 Fault::RateLimited => "rate_limited",
35 }
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct Failure {
41 pub fault: Fault,
42 pub message: String,
43 pub retry_after: Option<i64>,
44}
45
46impl Failure {
47 pub fn new(fault: Fault, message: impl Into<String>) -> Self {
48 Failure {
49 fault,
50 message: message.into(),
51 retry_after: None,
52 }
53 }
54
55 pub fn until(mut self, at: Option<i64>) -> Self {
56 self.retry_after = at;
57 self
58 }
59
60 pub fn text(&self) -> String {
61 format!("{}: {}", self.fault.word(), self.message)
62 }
63}