1use std::error;
2use std::fmt;
3
4use candid::Nat;
5
6#[derive(Debug, Clone)]
7pub struct ResponseContent<T> {
8 pub status: StatusCode,
9 pub content: String,
10 pub entity: Option<T>,
11}
12#[derive(Debug, Clone)]
13pub struct StatusCode(pub Nat);
14impl StatusCode {
15 pub fn is_success(&self) -> bool {
16 self.0 >= Nat::from(200_u8) && self.0 < Nat::from(300_u16)
17 }
18 pub fn is_client_error(&self) -> bool {
19 self.0 >= Nat::from(400_u16) && self.0 < Nat::from(500_u16)
20 }
21 pub fn is_server_error(&self) -> bool {
22 self.0 >= Nat::from(500_u16) && self.0 < Nat::from(600_u16)
23 }
24}
25impl From<Nat> for StatusCode {
26 fn from(n: Nat) -> Self {
27 StatusCode(n)
28 }
29}
30#[derive(Debug)]
31pub enum Error<T> {
32 Reqwest(std::io::Error),
33 Serde(serde_json::Error),
34 Io(std::io::Error),
35 ResponseError(ResponseContent<T>),
36}
37
38impl<T> fmt::Display for Error<T> {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 let (module, e) = match self {
41 Error::Reqwest(e) => ("reqwest", e.to_string()),
42 Error::Serde(e) => ("serde", e.to_string()),
43 Error::Io(e) => ("IO", e.to_string()),
44 Error::ResponseError(e) => ("response", format!("status code {:?}", e.status)),
45 };
46 write!(f, "error in {}: {}", module, e)
47 }
48}
49
50impl<T: fmt::Debug> error::Error for Error<T> {
51 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
52 Some(match self {
53 Error::Reqwest(e) => e,
54 Error::Serde(e) => e,
55 Error::Io(e) => e,
56 Error::ResponseError(_) => return None,
57 })
58 }
59}
60
61impl<T> From<serde_json::Error> for Error<T> {
62 fn from(e: serde_json::Error) -> Self {
63 Error::Serde(e)
64 }
65}
66
67impl<T> From<std::io::Error> for Error<T> {
68 fn from(e: std::io::Error) -> Self {
69 Error::Io(e)
70 }
71}
72
73pub fn urlencode<T: AsRef<str>>(s: T) -> String {
74 ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
75}
76
77pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> {
78 if let serde_json::Value::Object(object) = value {
79 let mut params = vec![];
80
81 for (key, value) in object {
82 match value {
83 serde_json::Value::Object(_) => params.append(&mut parse_deep_object(
84 &format!("{}[{}]", prefix, key),
85 value,
86 )),
87 serde_json::Value::Array(array) => {
88 for (i, value) in array.iter().enumerate() {
89 params.append(&mut parse_deep_object(
90 &format!("{}[{}][{}]", prefix, key, i),
91 value,
92 ));
93 }
94 }
95 serde_json::Value::String(s) => {
96 params.push((format!("{}[{}]", prefix, key), s.clone()))
97 }
98 _ => params.push((format!("{}[{}]", prefix, key), value.to_string())),
99 }
100 }
101
102 return params;
103 }
104
105 unimplemented!("Only objects are supported with style=deepObject")
106}
107
108pub mod state_api;
109pub mod statistics_api;
110pub mod status_api;
111pub mod stream_api;
112pub mod transaction_api;
113
114pub mod configuration;