use bytes::Bytes;
use std::time::Duration;
use reqwest::blocking::multipart;
use reqwest::blocking::Client;
use reqwest::blocking::ClientBuilder;
use reqwest::header;
use reqwest::header::HeaderValue;
use reqwest::StatusCode;
use crate::carbone_response::APIResponse;
use crate::config::Config;
use crate::errors::*;
use crate::render::*;
use crate::template::*;
use crate::types::{ApiJsonToken, JsonData};
use crate::types::Result;
#[derive(Debug, Clone)]
pub struct Carbone<'a> {
config: &'a Config,
http_client: Client,
}
impl<'a> Carbone<'a> {
pub fn new(config: &'a Config, api_token: &'a ApiJsonToken) -> Result<Self> {
let mut headers = header::HeaderMap::new();
headers.insert(
"carbone-version",
HeaderValue::from_str(config.api_version.as_str()).unwrap(),
);
let bearer = format!("Bearer {}", api_token.as_str());
let mut auth_value = header::HeaderValue::from_str(bearer.as_str()).unwrap();
auth_value.set_sensitive(true);
headers.insert(header::AUTHORIZATION, auth_value);
let http_client = ClientBuilder::new()
.default_headers(headers)
.timeout(Duration::from_secs(config.api_timeout))
.build()?;
Ok(Self {
config,
http_client,
})
}
pub fn delete_template(&self, template_id: TemplateId) -> Result<bool> {
let url = format!("{}/template/{}", self.config.api_url, template_id.as_str());
let response = self.http_client.delete(url).send();
match response {
Ok(response) => {
let json = response.json::<APIResponse>()?;
if json.success {
Ok(true)
} else {
Err(CarboneError::Error(json.error.unwrap()))
}
}
Err(e) => Err(CarboneError::RequestError(e)),
}
}
pub fn download_template(&self, template_id: &TemplateId) -> Result<Bytes> {
let url = format!("{}/template/{}", self.config.api_url, template_id.as_str());
let response = self.http_client.get(url).send();
match response {
Ok(r) => {
if r.status() == StatusCode::OK {
Ok(r.bytes()?)
} else {
let json = r.json::<APIResponse>()?;
Err(CarboneError::Error(json.error.unwrap()))
}
}
Err(e) => Err(CarboneError::RequestError(e)),
}
}
pub fn generate_report_with_file(
&self,
template_file: &TemplateFile,
json_data: JsonData,
payload: Option<&str>,
) -> Result<Bytes> {
let template_id_generated = template_file.generate_id(payload)?;
let result = self.download_template(&template_id_generated);
let template_id = if result.is_err() {
self.upload_template(&template_file, None)?
} else {
template_id_generated
};
let render_id = self.render_data(template_id, json_data)?;
let report_content = self.get_report(&render_id)?;
Ok(report_content)
}
pub fn get_report(&self, render_id: &RenderId) -> Result<Bytes> {
let url = format!("{}/render/{}", self.config.api_url, render_id.as_str());
let response = self.http_client.get(url).send();
match response {
Ok(r) => {
if r.status() == StatusCode::OK {
Ok(r.bytes()?)
} else {
let json = r.json::<APIResponse>()?;
Err(CarboneError::Error(json.error.unwrap()))
}
}
Err(e) => Err(CarboneError::RequestError(e)),
}
}
pub fn generate_report_with_template_id(
&self,
template_id: TemplateId,
json_data: JsonData,
) -> Result<Bytes> {
let render_id = self.render_data(template_id, json_data)?;
let report_content = self.get_report(&render_id)?;
Ok(report_content)
}
pub fn render_data(&self, template_id: TemplateId, json_data: JsonData) -> Result<RenderId> {
let url = format!("{}/render/{}", self.config.api_url, template_id.as_str());
let response = self
.http_client
.post(url)
.header("Content-Type", "application/json")
.body(json_data.as_str().to_owned())
.send();
match response {
Ok(response) => {
let json = response.json::<APIResponse>()?;
if json.success {
Ok(json.data.unwrap().render_id.unwrap())
} else {
Err(CarboneError::Error(json.error.unwrap()))
}
}
Err(e) => Err(CarboneError::RequestError(e)),
}
}
pub fn upload_template(
&self,
template_file: &TemplateFile,
salt: Option<&str>,
) -> Result<TemplateId> {
let salt = match salt {
Some(s) => s.to_string(),
None => "".to_string(),
};
let form = multipart::Form::new()
.text("", salt)
.file("template", template_file.path_as_str())?;
let url = format!("{}/template", self.config.api_url);
let response = self.http_client.post(url).multipart(form).send();
match response {
Ok(response) => {
let json = response.json::<APIResponse>()?;
if json.success {
Ok(json.data.unwrap().template_id.unwrap())
} else {
Err(CarboneError::Error(json.error.unwrap()))
}
}
Err(e) => Err(CarboneError::RequestError(e)),
}
}
}