1use crate::{ FormRequest, JsonRequest};
2
3use std::io::Error;
4use std::io::ErrorKind::NotFound;
5use std::path::PathBuf;
6use serde::{Deserialize, Serialize};
7use reqwest::multipart::Part;
8use async_trait::async_trait;
9use tokio::try_join;
10use crate::conversions::AsyncTryFrom;
11use crate::file_to_part;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct ImageRequest {
26 prompt: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 n: Option<u32>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 size: Option<ImageSize>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 response_format: Option<String>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 user: Option<String>,
35}
36
37impl JsonRequest<ImageResponse> for ImageRequest{
38 const ENDPOINT: &'static str = "/images/generations";
39}
40
41impl ImageRequest {
42 pub fn new(prompt: String) -> Self {
43 Self {
44 prompt,
45 n: None,
46 size: None,
47 response_format: None,
48 user: None,
49 }
50 }
51
52 pub fn n(mut self, n: u32) -> Self {
53 self.n = Some(n);
54 self
55 }
56
57 pub fn size(mut self, size: ImageSize) -> Self {
58 self.size = Some(size);
59 self
60 }
61
62 pub fn response_format(mut self, response_format: String) -> Self {
63 self.response_format = Some(response_format);
64 self
65 }
66
67 pub fn user(mut self, user: String) -> Self {
68 self.user = Some(user);
69 self
70 }
71}
72
73#[derive(Debug,Clone)]
89pub struct ImageEditRequest {
90 image: PathBuf,
91 mask: Option<PathBuf>,
92 prompt: String,
93 n: Option<i32>,
94 size: Option<ImageSize>,
95 response_format: Option<String>,
96 user: Option<String>
97}
98
99impl FormRequest<ImageResponse> for ImageEditRequest{
100 const ENDPOINT: &'static str = "/images/edits";
101}
102
103impl ImageEditRequest{
104
105 pub fn new(image:PathBuf, prompt: String) -> Result<Self,Error> {
107 if image.exists() {
108 return Ok(
109 Self {
110 image,
111 mask: None,
112 prompt,
113 n: None,
114 size: None,
115 response_format: None,
116 user: None,
117 })
118 }
119 Err(Error::new(NotFound, "File does not exist"))
120 }
121
122 pub fn mask(mut self, mask: PathBuf) -> Result<Self,Error> {
124 if mask.exists() {
125 self.mask = Some(mask);
126 return Ok(self)
127 }
128 Err(Error::new(NotFound, "File does not exist"))
129 }
130
131 pub fn n(mut self, n: i32) -> Self {
132 self.n = Some(n);
133 self
134 }
135
136 pub fn size(mut self, size: ImageSize) -> Self {
137 self.size = Some(size);
138 self
139 }
140
141 pub fn response_format(mut self, response_format: String) -> Self {
142 self.response_format = Some(response_format);
143 self
144 }
145
146 pub fn user(mut self, user: String) -> Self {
147 self.user = Some(user);
148 self
149 }
150
151}
152
153#[async_trait]
154impl AsyncTryFrom<ImageEditRequest> for reqwest::multipart::Form {
155
156 type Error = Error;
157
158 async fn try_from(request: ImageEditRequest) -> Result<Self, Self::Error> {
159 let mut form = reqwest::multipart::Form::new()
160 .part("prompt", Part::text(request.prompt));
161
162 if let Some(mask) = request.mask {
163 let (mask,image)= try_join!(file_to_part(&mask),file_to_part(&request.image))?;
164 form =
165 form.part("image", image)
166 .part("mask", mask);
167 }else {
168 form = form.part("image", file_to_part(&request.image).await?)
169 }
170 if let Some(n) = request.n {
171 form = form.part("n", Part::text(n.to_string()));
172 }
173 if let Some(size) = request.size {
174 form = form.part("size", Part::text(size.to_string()));
175 }
176 if let Some(response_format) = request.response_format {
177 form = form.part("response_format", Part::text(response_format));
178 }
179 if let Some(user) = request.user {
180 form = form.part("user", Part::text(user));
181 }
182 return Ok(form)
183 }
184}
185
186#[derive(Debug,Clone)]
199pub struct ImageVariationRequest {
200 image: PathBuf,
201 n: Option<u32>,
202 size: Option<ImageSize>,
203 user: Option<String>
204}
205
206impl FormRequest<ImageResponse> for ImageVariationRequest{
207 const ENDPOINT: &'static str = "/images/variations";
208}
209
210impl ImageVariationRequest {
211 pub fn new(image: PathBuf) -> Result<Self,Error> {
212 if image.exists() {
213 return Ok(
214 Self {
215 image,
216 n: None,
217 size: None,
218 user: None,
219 }
220 )
221 }
222 Err(Error::new(NotFound, "File does not exist"))
223 }
224
225 pub fn n(mut self, n: u32) -> Self {
226 self.n = Some(n);
227 self
228 }
229
230 pub fn size(mut self, size: ImageSize) -> Self {
231 self.size = Some(size);
232 self
233 }
234
235 pub fn user(mut self, user: String) -> Self {
236 self.user = Some(user);
237 self
238 }
239}
240
241#[async_trait]
242impl AsyncTryFrom<ImageVariationRequest> for reqwest::multipart::Form {
243
244 type Error = Error;
245
246 async fn try_from(request: ImageVariationRequest) -> Result<Self, Self::Error> {
247 let mut form = reqwest::multipart::Form::new()
248 .part("image", file_to_part(&request.image).await?);
249 if let Some(n) = request.n {
250 form = form.part("n", Part::text(n.to_string()));
251 }
252 if let Some(size) = request.size {
253 form = form.part("size", Part::text(size.to_string()));
254 }
255 if let Some(user) = request.user {
256 form = form.part("user", Part::text(user));
257 }
258 return Ok(form)
259 }
260}
261
262
263#[derive(Debug,Clone,Serialize,Deserialize)]
264pub struct ImageResponse {
265 pub created: i64,
266 pub data: Vec<ImageData>,
267}
268
269#[derive(Debug,Clone,Serialize, Deserialize)]
270pub struct ImageData {
271 pub url: String,
272}
273
274#[derive(Debug,Clone, Serialize, Deserialize)]
275pub enum ImageSize {
276 #[serde(rename = "256x256")]
277 S256,
278 #[serde(rename = "512x512")]
279 S512,
280 #[serde(rename = "1024x1024")]
281 S1024,
282}
283
284impl ToString for ImageSize {
285 fn to_string(&self) -> String {
286 match *self {
287 ImageSize::S256 => String::from("256x256"),
288 ImageSize::S512 => String::from("512x512"),
289 ImageSize::S1024 => String::from("1024x1024"),
290 }
291 }
292}
293
294impl ImageSize {
295 pub fn from_string(s: &str) -> Option<Self> {
296 match s {
297 "256x256" => Some(ImageSize::S256),
298 "512x512" => Some(ImageSize::S512),
299 "1024x1024" => Some(ImageSize::S1024),
300 _ => None,
301 }
302 }
303}
304
305