1#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error)]
2pub enum APIErrorCode {
3 #[error("Invalid inputs.")]
4 InvalidRequest,
5 #[error("An error occured during the execution of this API call.")]
6 InternalError,
7 #[error("The request was denied. The wallet may be disconnected.")]
8 Refused,
9 #[error("The account has changed.")]
11 AccountChange,
12 #[error("Unknown error code `{0}'")]
13 Unknown(i64),
14}
15
16#[derive(
17 Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error, serde::Deserialize,
18)]
19#[error("{code}. {info}.")]
20pub struct APIError {
21 pub code: APIErrorCode,
22 pub info: String,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error)]
26pub enum DataSignErrorCode {
27 #[error(
28 "Wallet could not sign the data (e.g. does not have the secret key associated with the address)"
29 )]
30 ProofGeneration,
31 #[error("Address was not a P2PK address and thus had no SK associated with it")]
32 AddressNotPK,
33 #[error("User declined to sign the data")]
34 UserDeclined,
35 #[error("Unknown error code `{0}'")]
36 Unknown(u64),
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error)]
40#[error("{code}. {info}.")]
41pub struct DataSignError {
42 pub code: DataSignErrorCode,
43 pub info: String,
44}
45
46#[derive(
47 Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, thiserror::Error, serde::Deserialize,
48)]
49#[serde(rename_all = "camelCase")]
50#[error("Pagination error")]
51pub struct PaginateError {
52 pub max_size: usize,
53}
54
55impl<'de> serde::Deserialize<'de> for APIErrorCode {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: serde::Deserializer<'de>,
59 {
60 struct Visitor;
61 impl serde::de::Visitor<'_> for Visitor {
62 type Value = APIErrorCode;
63
64 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
65 write!(formatter, "Expecting an integer APIErrorCode")
66 }
67
68 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
69 where
70 E: serde::de::Error,
71 {
72 match v {
73 -1 => Ok(APIErrorCode::InvalidRequest),
74 -2 => Ok(APIErrorCode::InternalError),
75 -3 => Ok(APIErrorCode::Refused),
76 -4 => Ok(APIErrorCode::AccountChange),
77 unknown => Ok(APIErrorCode::Unknown(unknown)),
78 }
79 }
80 }
81
82 deserializer.deserialize_i64(Visitor)
83 }
84}
85
86impl<'de> serde::Deserialize<'de> for DataSignErrorCode {
87 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
88 where
89 D: serde::Deserializer<'de>,
90 {
91 struct Visitor;
92 impl serde::de::Visitor<'_> for Visitor {
93 type Value = DataSignErrorCode;
94
95 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
96 write!(formatter, "Expecting an integer DataSignErrorCode")
97 }
98
99 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
100 where
101 E: serde::de::Error,
102 {
103 match v {
104 1 => Ok(DataSignErrorCode::ProofGeneration),
105 2 => Ok(DataSignErrorCode::AddressNotPK),
106 3 => Ok(DataSignErrorCode::UserDeclined),
107 unknown => Ok(DataSignErrorCode::Unknown(unknown)),
108 }
109 }
110 }
111
112 deserializer.deserialize_u64(Visitor)
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use serde_json::json;
119
120 use super::*;
121
122 #[test]
123 fn api_error_code_json() {
124 assert_eq!(
125 serde_json::from_value::<APIErrorCode>(json! { -1 }).unwrap(),
126 APIErrorCode::InvalidRequest
127 );
128 assert_eq!(
129 serde_json::from_value::<APIErrorCode>(json! { -2 }).unwrap(),
130 APIErrorCode::InternalError
131 );
132 assert_eq!(
133 serde_json::from_value::<APIErrorCode>(json! { -3 }).unwrap(),
134 APIErrorCode::Refused
135 );
136 assert_eq!(
137 serde_json::from_value::<APIErrorCode>(json! { -4 }).unwrap(),
138 APIErrorCode::AccountChange
139 );
140 assert_eq!(
141 serde_json::from_value::<APIErrorCode>(json! { -42 }).unwrap(),
142 APIErrorCode::Unknown(-42)
143 );
144 }
145
146 #[test]
147 fn api_error_json() {
148 assert_eq!(
149 serde_json::from_value::<APIError>(json! { {
150 "code": -1,
151 "info": "Parameter malformed.",
152 }})
153 .unwrap(),
154 APIError {
155 code: APIErrorCode::InvalidRequest,
156 info: "Parameter malformed.".to_owned()
157 }
158 );
159
160 assert_eq!(
161 serde_json::from_value::<APIError>(json! { {
162 "code": -2,
163 "info": "Internal Error.",
164 }})
165 .unwrap(),
166 APIError {
167 code: APIErrorCode::InternalError,
168 info: "Internal Error.".to_owned()
169 }
170 );
171
172 assert_eq!(
173 serde_json::from_value::<APIError>(json! { {
174 "code": -3,
175 "info": "Access Denied.",
176 }})
177 .unwrap(),
178 APIError {
179 code: APIErrorCode::Refused,
180 info: "Access Denied.".to_owned()
181 }
182 );
183
184 assert_eq!(
185 serde_json::from_value::<APIError>(json! { {
186 "code": -4,
187 "info": "Account has changed.",
188 }})
189 .unwrap(),
190 APIError {
191 code: APIErrorCode::AccountChange,
192 info: "Account has changed.".to_owned()
193 }
194 );
195 }
196
197 #[test]
198 fn sign_data_error_code_json() {
199 assert_eq!(
200 serde_json::from_value::<DataSignErrorCode>(json! { 1 }).unwrap(),
201 DataSignErrorCode::ProofGeneration
202 );
203 assert_eq!(
204 serde_json::from_value::<DataSignErrorCode>(json! { 2 }).unwrap(),
205 DataSignErrorCode::AddressNotPK
206 );
207 assert_eq!(
208 serde_json::from_value::<DataSignErrorCode>(json! { 3 }).unwrap(),
209 DataSignErrorCode::UserDeclined
210 );
211 assert_eq!(
212 serde_json::from_value::<DataSignErrorCode>(json! { 42 }).unwrap(),
213 DataSignErrorCode::Unknown(42)
214 );
215 }
216}