use std::error;
use std::fmt;
#[derive(Debug, Clone)]
pub struct ResponseContent<T> {
pub status: reqwest::StatusCode,
pub content: String,
pub entity: Option<T>,
}
#[derive(Debug)]
pub enum Error<T> {
Reqwest(reqwest::Error),
Serde(serde_json::Error),
Io(std::io::Error),
ResponseError(ResponseContent<T>),
}
impl<T: fmt::Debug> fmt::Display for Error<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (module, e) = match self {
Error::Reqwest(e) => ("reqwest", e.to_string()),
Error::Serde(e) => ("serde", e.to_string()),
Error::Io(e) => ("IO", e.to_string()),
Error::ResponseError(e) => {
let detail = e
.entity
.as_ref()
.map(|en| format!(" — {en:?}"))
.unwrap_or_default();
("response", format!("status code {}{}", e.status, detail))
}
};
write!(f, "error in {}: {}", module, e)
}
}
impl<T: fmt::Debug> error::Error for Error<T> {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match self {
Error::Reqwest(e) => e,
Error::Serde(e) => e,
Error::Io(e) => e,
Error::ResponseError(_) => return None,
})
}
}
impl<T> From<reqwest::Error> for Error<T> {
fn from(e: reqwest::Error) -> Self {
Error::Reqwest(e)
}
}
impl<T> From<serde_json::Error> for Error<T> {
fn from(e: serde_json::Error) -> Self {
Error::Serde(e)
}
}
impl<T> From<std::io::Error> for Error<T> {
fn from(e: std::io::Error) -> Self {
Error::Io(e)
}
}
pub fn urlencode<T: AsRef<str>>(s: T) -> String {
use percent_encoding::{AsciiSet, CONTROLS, utf8_percent_encode};
const PATH_SEGMENT: &AsciiSet = &CONTROLS
.add(b' ')
.add(b'"')
.add(b'<')
.add(b'>')
.add(b'`')
.add(b'#')
.add(b'?')
.add(b'{')
.add(b'}')
.add(b'/')
.add(b'%')
.add(b'@')
.add(b':');
utf8_percent_encode(s.as_ref(), PATH_SEGMENT).to_string()
}
pub async fn parse_response<T, E>(resp: reqwest::Response) -> Result<T, Error<E>>
where
T: serde::de::DeserializeOwned,
E: serde::de::DeserializeOwned,
{
let status = resp.status();
let content = resp.text().await?;
if status.is_success() {
serde_json::from_str(&content).map_err(Error::from)
} else {
let entity = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub async fn parse_empty_response<E>(resp: reqwest::Response) -> Result<(), Error<E>>
where
E: serde::de::DeserializeOwned,
{
let status = resp.status();
if status.is_success() {
Ok(())
} else {
let content = resp.text().await?;
let entity = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent {
status,
content,
entity,
}))
}
}
pub mod assertions_api;
pub mod auth_zen_service_api;
pub mod authorization_models_api;
pub mod relationship_queries_api;
pub mod relationship_tuples_api;
pub mod stores_api;
pub mod configuration;