headless_common/api/
mod.rs1use std::error;
2use std::fmt;
3
4pub mod field_collection;
5pub mod filter;
6pub mod page_params;
7pub mod sort;
8
9#[derive(Debug, Clone)]
10pub struct ResponseContent<T> {
11 pub status: reqwest::StatusCode,
12 pub content: String,
13 pub entity: Option<T>,
14}
15
16#[derive(Debug)]
17pub enum Error<T> {
18 Reqwest(reqwest::Error),
19 Serde(serde_json::Error),
20 Io(std::io::Error),
21 ResponseError(ResponseContent<T>),
22}
23
24impl<T> fmt::Display for Error<T> {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 let (module, e) = match self {
27 Error::Reqwest(e) => ("reqwest", e.to_string()),
28 Error::Serde(e) => ("serde", e.to_string()),
29 Error::Io(e) => ("IO", e.to_string()),
30 Error::ResponseError(e) => ("response", format!("status code {}", e.status)),
31 };
32 write!(f, "error in {module}: {e}")
33 }
34}
35
36impl<T: fmt::Debug> error::Error for Error<T> {
37 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
38 Some(match self {
39 Error::Reqwest(e) => e,
40 Error::Serde(e) => e,
41 Error::Io(e) => e,
42 Error::ResponseError(_) => return None,
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(_) => {
76 params.append(&mut parse_deep_object(&format!("{prefix}[{key}]"), value))
77 }
78 serde_json::Value::Array(array) => {
79 for (i, value) in array.iter().enumerate() {
80 params.append(&mut parse_deep_object(
81 &format!("{prefix}[{key}][{i}]"),
82 value,
83 ));
84 }
85 }
86 serde_json::Value::String(s) => {
87 params.push((format!("{prefix}[{key}]"), s.clone()))
88 }
89 _ => params.push((format!("{prefix}[{key}]"), value.to_string())),
90 }
91 }
92
93 return params;
94 }
95
96 unimplemented!("Only objects are supported with style=deepObject")
97}