ckb_light_client_protocol_server/
status.rs1use std::{fmt, time::Duration};
2
3use crate::constant;
4
5#[repr(u16)]
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16pub enum StatusCode {
17 OK = 200,
19
20 MalformedProtocolMessage = 400,
22 UnexpectedProtocolMessage = 401,
24
25 InvalidRequest = 410,
27 InvalidLastBlock = 411,
29 InvalidUnconfirmedBlock = 412,
31 InvaildDifficultyBoundary = 413,
33
34 InternalError = 500,
36 Network = 501,
38}
39
40#[derive(Clone, Debug, Eq)]
42pub struct Status {
43 code: StatusCode,
44 context: Option<String>,
45}
46
47impl PartialEq for Status {
48 fn eq(&self, other: &Self) -> bool {
49 self.code == other.code
50 }
51}
52
53impl fmt::Display for Status {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 match self.context {
56 Some(ref context) => write!(f, "{:?}({}): {}", self.code, self.code as u16, context),
57 None => write!(f, "{:?}({})", self.code, self.code as u16),
58 }
59 }
60}
61
62impl From<StatusCode> for Status {
63 fn from(code: StatusCode) -> Self {
64 Self::new::<&str>(code, None)
65 }
66}
67
68impl StatusCode {
69 pub fn with_context<S: ToString>(self, context: S) -> Status {
71 Status::new(self, Some(context))
72 }
73}
74
75impl Status {
76 pub fn new<T: ToString>(code: StatusCode, context: Option<T>) -> Self {
78 Self {
79 code,
80 context: context.map(|c| c.to_string()),
81 }
82 }
83
84 pub fn ok() -> Self {
86 Self::new::<&str>(StatusCode::OK, None)
87 }
88
89 pub fn is_ok(&self) -> bool {
91 self.code == StatusCode::OK
92 }
93
94 pub fn should_ban(&self) -> Option<Duration> {
96 let code = self.code as u16;
97 if !(400..500).contains(&code) {
98 None
99 } else {
100 Some(constant::BAD_MESSAGE_BAN_TIME)
101 }
102 }
103
104 pub fn should_warn(&self) -> bool {
106 let code = self.code as u16;
107 (500..600).contains(&code)
108 }
109
110 pub fn code(&self) -> StatusCode {
112 self.code
113 }
114}