use crate::error::{Error, Result};
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct ServiceResponse<T> {
#[serde(default = "none")]
pub result: Option<T>,
#[serde(default)]
pub successful: bool,
#[serde(default)]
pub message: Option<String>,
}
impl<T> ServiceResponse<T> {
pub fn into_result(self) -> Result<T> {
if self.successful {
self.result.ok_or_else(|| Error::Api {
message: self
.message
.unwrap_or_else(|| "successful response carried no `result` payload".into()),
code: None,
errors: Vec::new(),
})
} else {
Err(Error::Api {
message: self.message.unwrap_or_else(|| "request was not successful".into()),
code: None,
errors: Vec::new(),
})
}
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Envelope<T> {
#[serde(default = "none")]
pub result: Option<T>,
#[serde(default)]
pub error_message: Option<String>,
#[serde(default)]
pub error_messages: Vec<String>,
#[serde(default)]
pub has_error: bool,
#[serde(default)]
pub time_generated: Option<String>,
}
impl<T> Envelope<T> {
pub fn into_result(self) -> Result<T> {
if self.has_error {
let message = self
.error_message
.filter(|m| !m.is_empty())
.or_else(|| self.error_messages.first().cloned())
.unwrap_or_else(|| "request returned an error".into());
return Err(Error::Api {
message,
code: None,
errors: self.error_messages,
});
}
self.result.ok_or_else(|| Error::Api {
message: "response reported no error but carried no `result` payload".into(),
code: None,
errors: Vec::new(),
})
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ApiResponse<T> {
#[serde(default = "none")]
pub data: Option<T>,
#[serde(default)]
pub status: bool,
#[serde(default)]
pub message: Option<String>,
#[serde(default)]
pub code: Option<String>,
#[serde(default)]
pub status_code: Option<String>,
#[serde(default)]
pub errors: Vec<String>,
}
impl<T> ApiResponse<T> {
pub fn into_result(self) -> Result<T> {
if self.status {
self.data.ok_or_else(|| Error::Api {
message: self
.message
.unwrap_or_else(|| "successful response carried no `data` payload".into()),
code: self.code,
errors: self.errors,
})
} else {
Err(Error::Api {
message: self.message.unwrap_or_else(|| "request was not successful".into()),
code: self.code,
errors: self.errors,
})
}
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StatusResponse {
#[serde(default)]
pub status: bool,
#[serde(default)]
pub message: Option<String>,
#[serde(default)]
pub code: Option<String>,
#[serde(default)]
pub status_code: Option<String>,
#[serde(default)]
pub errors: Vec<String>,
}
impl StatusResponse {
pub fn into_result(self) -> Result<Acknowledgement> {
if self.status {
Ok(Acknowledgement {
message: self.message,
code: self.code,
})
} else {
Err(Error::Api {
message: self.message.unwrap_or_else(|| "request was not successful".into()),
code: self.code,
errors: self.errors,
})
}
}
}
#[derive(Debug, Clone)]
pub struct Acknowledgement {
pub message: Option<String>,
pub code: Option<String>,
}
fn none<T>() -> Option<T> {
None
}