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