use async_trait::async_trait;
use bytes::Bytes;
use crate::Context;
use crate::Error;
use crate::model::ErrorBody;
use crate::model::ErrorsBody;
use crate::model::Template;
use reqwest::Body;
use reqwest::multipart::Form;
use reqwest::multipart::Part;
use uuid::Uuid;
pub enum TemplateError {
Error400(ErrorsBody),
Error401(ErrorBody),
Error403(ErrorBody),
Error404(ErrorBody),
Error409(ErrorBody),
Error500(ErrorBody),
}
#[async_trait]
pub trait TemplateClient {
async fn get_template_by_id(&self, template_id: &Uuid) -> Result<Vec<Template>, Error<TemplateError>>;
async fn update_template(&self, template_id: &Uuid, value: impl Into<Body> + Send) -> Result<Template, Error<TemplateError>>;
async fn get_all_templates(&self, template_name: Option<&str>) -> Result<Vec<Template>, Error<TemplateError>>;
async fn upload_template(&self, name: &str, template: impl Into<Body> + Send) -> Result<Template, Error<TemplateError>>;
async fn download_template(&self, template_id: &Uuid, version: Option<i32>) -> Result<Bytes, Error<TemplateError>>;
async fn get_latest_version(&self, template_id: &Uuid) -> Result<i32, Error<TemplateError>>;
}
pub struct TemplateClientLive {
pub context: Context,
}
#[async_trait]
impl TemplateClient for TemplateClientLive {
async fn get_template_by_id(&self, template_id: &Uuid) -> Result<Vec<Template>, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates")
.push(&template_id.to_string());
let mut request = self
.context
.client
.get(url.clone());
{
tracing::info!(method="get", endpoint="/v2/templates/{template_id}", url=url.to_string(), "get_template_by_id");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.json::<Vec<Template>>().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
async fn update_template(&self, template_id: &Uuid, value: impl Into<Body> + Send) -> Result<Template, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates")
.push(&template_id.to_string())
.push("upload");
let mut request = self
.context
.client
.put(url.clone());
{
tracing::info!(method="put", endpoint="/v2/templates/{template_id}/upload", url=url.to_string(), body="<binary>", "update_template");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
request = request.body(value);
request = request.header(reqwest::header::CONTENT_TYPE, "application/octet-stream");
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.json::<Template>().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
async fn get_all_templates(&self, template_name: Option<&str>) -> Result<Vec<Template>, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates");
if let Some(template_name) = template_name {
url.query_pairs_mut().append_pair("template-name", &template_name);
}
let mut request = self
.context
.client
.get(url.clone());
{
tracing::info!(method="get", endpoint="/v2/templates", url=url.to_string(), "get_all_templates");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.json::<Vec<Template>>().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
async fn upload_template(&self, name: &str, template: impl Into<Body> + Send) -> Result<Template, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates");
let mut request = self
.context
.client
.post(url.clone());
{
tracing::info!(method="post", endpoint="/v2/templates", url=url.to_string(), body="<multipart>", "upload_template");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
let form = Form::new()
.part("name", Part::text(name.to_string()).mime_str("text/plain; charset=utf-8")?)
.part("template", Part::stream(template).mime_str("application/octet-stream")?);
request = request.multipart(form);
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.json::<Template>().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
async fn download_template(&self, template_id: &Uuid, version: Option<i32>) -> Result<Bytes, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates")
.push(&template_id.to_string())
.push("download");
if let Some(version) = version {
url.query_pairs_mut().append_pair("version", &version.to_string());
}
let mut request = self
.context
.client
.get(url.clone());
{
tracing::info!(method="get", endpoint="/v2/templates/{template_id}/download", url=url.to_string(), "download_template");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.bytes().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
async fn get_latest_version(&self, template_id: &Uuid) -> Result<i32, Error<TemplateError>> {
let mut url = self.context.base_url.clone();
url.path_segments_mut().unwrap()
.push("v2")
.push("templates")
.push(&template_id.to_string())
.push("latest");
let mut request = self
.context
.client
.get(url.clone());
{
tracing::info!(method="get", endpoint="/v2/templates/{template_id}/latest", url=url.to_string(), "get_latest_version");
}
if let Some(token) = self.context.bearer_token() {
request = request.bearer_auth(token);
}
let response = request.send().await?;
let status = response.status().as_u16();
match status {
200 => {
Ok(response.json::<i32>().await?)
}
400 => {
let body = response.json::<ErrorsBody>().await?;
Err(Error::Item(TemplateError::Error400(body)))
}
401 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error401(body)))
}
403 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error403(body)))
}
404 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error404(body)))
}
409 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error409(body)))
}
500 => {
let body = response.json::<ErrorBody>().await?;
Err(Error::Item(TemplateError::Error500(body)))
}
_ => Err(Error::unexpected(status, response.bytes().await?)),
}
}
}