1use std::io::{ErrorKind, Read};
17use reqwest::blocking::multipart;
18use crate::error::ToonifyError;
19
20pub struct ToonifyFile {
21 #[doc(hidden)]
22 response: Result<std::string::String, String>
23}
24
25#[doc(hidden)]
26struct ToonifyFileInternal {
27 api_key: String,
28 image_file: String
29}
30
31impl ToonifyFile {
32
33 pub fn new(image_file: &str, api_key: &str) -> Self {
37 let internal = ToonifyFileInternal::new(image_file, api_key);
38 let response = internal.http();
39 Self {
40 response
41 }
42 }
43
44 #[doc(hidden)]
45 fn is_error(&self) -> Option<std::string::String> {
46 match self.response.clone() {
47 Ok(response) => match json::parse(&response) {
48 Ok(json) => if json.has_key("err") {
49 Some(json["err"].to_string())
50 } else if json.has_key("status") {
51 Some(json["status"].to_string())
52 } else {
53 None
54 },
55 Err(_) => None
56 },
57 Err(err) => if err.is_empty() {
58 None
59 } else {
60 Some(err)
61 }
62 }
63 }
64
65 #[doc(hidden)]
66 fn json(&self, key: &str) -> Option<std::string::String> {
67 match self.response.clone() {
68 Ok(response) => match json::parse(&response) {
69 Ok(json) => if json.has_key(key) {
70 Some(json[key].to_string())
71 } else {
72 None
73 },
74 Err(_) => None
75 },
76 Err(_) => None
77 }
78 }
79
80 pub fn image(&self) -> Result<std::string::String, ToonifyError> {
82 match self.is_error() {
83 Some(error) => Err(ToonifyError::Error(error)),
84 None => match self.json("output_url") {
85 Some(image) => Ok(image),
86 None => Err(ToonifyError::Null(String::from("null")))
87 }
88 }
89 }
90
91 pub fn id(&self) -> Result<std::string::String, ToonifyError> {
93 match self.is_error() {
94 Some(error) => Err(ToonifyError::Error(error)),
95 None => match self.json("id") {
96 Some(id) => Ok(id),
97 None => Err(ToonifyError::Null(String::from("null")))
98 }
99 }
100 }
101}
102
103impl ToonifyFileInternal {
104 fn new(image_file: &str, api_key: &str) -> Self {
105 Self {
106 api_key: api_key.to_string(),
107 image_file: image_file.to_string()
108 }
109 }
110
111 fn http(&self) -> Result<std::string::String, String> {
112 match multipart::Form::new().file("image", &self.image_file) {
113 Ok(form) => match reqwest::blocking::Client::new()
114 .post("https://api.deepai.org/api/toonify")
115 .header("api-key", self.api_key.clone())
116 .multipart(form)
117 .send() {
118 Ok(mut data) => {
119 let mut body = std::string::String::new();
120 match data.read_to_string(&mut body) {
121 Ok(_) => Ok(body),
122 Err(_) => Err("".to_string())
123 }
124 },
125 Err(_) => Err("".to_string())
126 },
127 Err(err) => match err.kind() {
128 ErrorKind::NotFound => Err(err.to_string()),
129 _ => Err("".to_string())
130 }
131 }
132 }
133}