use std::io::{ErrorKind, Read};
use reqwest::blocking::multipart;
use crate::error::ToonifyError;
pub struct ToonifyFile {
#[doc(hidden)]
response: Result<std::string::String, String>
}
#[doc(hidden)]
struct ToonifyFileInternal {
api_key: String,
image_file: String
}
impl ToonifyFile {
pub fn new(image_file: &str, api_key: &str) -> Self {
let internal = ToonifyFileInternal::new(image_file, api_key);
let response = internal.http();
Self {
response
}
}
#[doc(hidden)]
fn is_error(&self) -> Option<std::string::String> {
match self.response.clone() {
Ok(response) => match json::parse(&response) {
Ok(json) => if json.has_key("err") {
Some(json["err"].to_string())
} else if json.has_key("status") {
Some(json["status"].to_string())
} else {
None
},
Err(_) => None
},
Err(err) => if err.is_empty() {
None
} else {
Some(err)
}
}
}
#[doc(hidden)]
fn json(&self, key: &str) -> Option<std::string::String> {
match self.response.clone() {
Ok(response) => match json::parse(&response) {
Ok(json) => if json.has_key(key) {
Some(json[key].to_string())
} else {
None
},
Err(_) => None
},
Err(_) => None
}
}
pub fn image(&self) -> Result<std::string::String, ToonifyError> {
match self.is_error() {
Some(error) => Err(ToonifyError::Error(error)),
None => match self.json("output_url") {
Some(image) => Ok(image),
None => Err(ToonifyError::Null(String::from("null")))
}
}
}
pub fn id(&self) -> Result<std::string::String, ToonifyError> {
match self.is_error() {
Some(error) => Err(ToonifyError::Error(error)),
None => match self.json("id") {
Some(id) => Ok(id),
None => Err(ToonifyError::Null(String::from("null")))
}
}
}
}
impl ToonifyFileInternal {
fn new(image_file: &str, api_key: &str) -> Self {
Self {
api_key: api_key.to_string(),
image_file: image_file.to_string()
}
}
fn http(&self) -> Result<std::string::String, String> {
match multipart::Form::new().file("image", &self.image_file) {
Ok(form) => match reqwest::blocking::Client::new()
.post("https://api.deepai.org/api/toonify")
.header("api-key", self.api_key.clone())
.multipart(form)
.send() {
Ok(mut data) => {
let mut body = std::string::String::new();
match data.read_to_string(&mut body) {
Ok(_) => Ok(body),
Err(_) => Err("".to_string())
}
},
Err(_) => Err("".to_string())
},
Err(err) => match err.kind() {
ErrorKind::NotFound => Err(err.to_string()),
_ => Err("".to_string())
}
}
}
}