1use std::{
2 fmt::Display,
3 path::{Path, PathBuf},
4};
5
6use crate::{
7 download::{download_url, save_b64},
8 error::OpenAIError,
9 traits::AsyncTryFrom,
10 types::InputSource,
11 util::{create_all_dir, create_file_part},
12};
13
14use bytes::Bytes;
15
16use super::{
17 responses::{CodeInterpreterContainer, Input, InputContent, Role as ResponsesRole},
18 AddUploadPartRequest, AudioInput, AudioResponseFormat, ChatCompletionFunctionCall,
19 ChatCompletionFunctions, ChatCompletionNamedToolChoice, ChatCompletionRequestAssistantMessage,
20 ChatCompletionRequestAssistantMessageContent, ChatCompletionRequestDeveloperMessage,
21 ChatCompletionRequestDeveloperMessageContent, ChatCompletionRequestFunctionMessage,
22 ChatCompletionRequestMessage, ChatCompletionRequestMessageContentPartAudio,
23 ChatCompletionRequestMessageContentPartImage, ChatCompletionRequestMessageContentPartText,
24 ChatCompletionRequestSystemMessage, ChatCompletionRequestSystemMessageContent,
25 ChatCompletionRequestToolMessage, ChatCompletionRequestToolMessageContent,
26 ChatCompletionRequestUserMessage, ChatCompletionRequestUserMessageContent,
27 ChatCompletionRequestUserMessageContentPart, ChatCompletionToolChoiceOption, CreateFileRequest,
28 CreateImageEditRequest, CreateImageVariationRequest, CreateMessageRequestContent,
29 CreateSpeechResponse, CreateTranscriptionRequest, CreateTranslationRequest, DallE2ImageSize,
30 EmbeddingInput, FileInput, FilePurpose, FunctionName, Image, ImageInput, ImageModel,
31 ImageResponseFormat, ImageSize, ImageUrl, ImagesResponse, ModerationInput, Prompt, Role, Stop,
32 TimestampGranularity, FileExpiresAfterAnchor
33};
34
35macro_rules! impl_from {
44 ($from_typ:ty, $to_typ:ty) => {
45 impl From<$from_typ> for $to_typ {
47 fn from(value: $from_typ) -> Self {
48 <$to_typ>::String(value.into())
49 }
50 }
51
52 impl From<Vec<$from_typ>> for $to_typ {
54 fn from(value: Vec<$from_typ>) -> Self {
55 <$to_typ>::StringArray(value.iter().map(|v| v.to_string()).collect())
56 }
57 }
58
59 impl From<&Vec<$from_typ>> for $to_typ {
61 fn from(value: &Vec<$from_typ>) -> Self {
62 <$to_typ>::StringArray(value.iter().map(|v| v.to_string()).collect())
63 }
64 }
65
66 impl<const N: usize> From<[$from_typ; N]> for $to_typ {
68 fn from(value: [$from_typ; N]) -> Self {
69 <$to_typ>::StringArray(value.into_iter().map(|v| v.to_string()).collect())
70 }
71 }
72
73 impl<const N: usize> From<&[$from_typ; N]> for $to_typ {
75 fn from(value: &[$from_typ; N]) -> Self {
76 <$to_typ>::StringArray(value.into_iter().map(|v| v.to_string()).collect())
77 }
78 }
79 };
80}
81
82impl_from!(&str, Prompt);
84impl_from!(String, Prompt);
85impl_from!(&String, Prompt);
86
87impl_from!(&str, Stop);
89impl_from!(String, Stop);
90impl_from!(&String, Stop);
91
92impl_from!(&str, ModerationInput);
94impl_from!(String, ModerationInput);
95impl_from!(&String, ModerationInput);
96
97impl_from!(&str, EmbeddingInput);
99impl_from!(String, EmbeddingInput);
100impl_from!(&String, EmbeddingInput);
101
102macro_rules! impl_default {
104 ($for_typ:ty) => {
105 impl Default for $for_typ {
106 fn default() -> Self {
107 Self::String("".into())
108 }
109 }
110 };
111}
112
113impl_default!(Prompt);
114impl_default!(ModerationInput);
115impl_default!(EmbeddingInput);
116
117impl Default for InputSource {
118 fn default() -> Self {
119 InputSource::Path {
120 path: PathBuf::new(),
121 }
122 }
123}
124
125macro_rules! impl_input {
134 ($for_typ:ty) => {
135 impl $for_typ {
136 pub fn from_bytes(filename: String, bytes: Bytes) -> Self {
137 Self {
138 source: InputSource::Bytes { filename, bytes },
139 }
140 }
141
142 pub fn from_vec_u8(filename: String, vec: Vec<u8>) -> Self {
143 Self {
144 source: InputSource::VecU8 { filename, vec },
145 }
146 }
147 }
148
149 impl<P: AsRef<Path>> From<P> for $for_typ {
150 fn from(path: P) -> Self {
151 let path_buf = path.as_ref().to_path_buf();
152 Self {
153 source: InputSource::Path { path: path_buf },
154 }
155 }
156 }
157 };
158}
159
160impl_input!(AudioInput);
161impl_input!(FileInput);
162impl_input!(ImageInput);
163
164impl Display for ImageSize {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 write!(
167 f,
168 "{}",
169 match self {
170 Self::S256x256 => "256x256",
171 Self::S512x512 => "512x512",
172 Self::S1024x1024 => "1024x1024",
173 Self::S1792x1024 => "1792x1024",
174 Self::S1024x1792 => "1024x1792",
175 }
176 )
177 }
178}
179
180impl Display for DallE2ImageSize {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 write!(
183 f,
184 "{}",
185 match self {
186 Self::S256x256 => "256x256",
187 Self::S512x512 => "512x512",
188 Self::S1024x1024 => "1024x1024",
189 }
190 )
191 }
192}
193
194impl Display for ImageModel {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 write!(
197 f,
198 "{}",
199 match self {
200 Self::DallE2 => "dall-e-2",
201 Self::DallE3 => "dall-e-3",
202 Self::Other(other) => other,
203 }
204 )
205 }
206}
207
208impl Display for ImageResponseFormat {
209 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
210 write!(
211 f,
212 "{}",
213 match self {
214 Self::Url => "url",
215 Self::B64Json => "b64_json",
216 }
217 )
218 }
219}
220
221impl Display for AudioResponseFormat {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 write!(
224 f,
225 "{}",
226 match self {
227 AudioResponseFormat::Json => "json",
228 AudioResponseFormat::Srt => "srt",
229 AudioResponseFormat::Text => "text",
230 AudioResponseFormat::VerboseJson => "verbose_json",
231 AudioResponseFormat::Vtt => "vtt",
232 }
233 )
234 }
235}
236
237impl Display for TimestampGranularity {
238 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
239 write!(
240 f,
241 "{}",
242 match self {
243 TimestampGranularity::Word => "word",
244 TimestampGranularity::Segment => "segment",
245 }
246 )
247 }
248}
249
250impl Display for Role {
251 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
252 write!(
253 f,
254 "{}",
255 match self {
256 Role::User => "user",
257 Role::System => "system",
258 Role::Assistant => "assistant",
259 Role::Function => "function",
260 Role::Tool => "tool",
261 }
262 )
263 }
264}
265
266impl Display for FilePurpose {
267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268 write!(
269 f,
270 "{}",
271 match self {
272 Self::Assistants => "assistants",
273 Self::Batch => "batch",
274 Self::FineTune => "fine-tune",
275 Self::Vision => "vision",
276 }
277 )
278 }
279}
280
281impl Display for FileExpiresAfterAnchor {
282 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
283 write!(
284 f,
285 "{}",
286 match self {
287 Self::CreatedAt => "created_at",
288 }
289 )
290 }
291}
292
293impl ImagesResponse {
294 pub async fn save<P: AsRef<Path>>(&self, dir: P) -> Result<Vec<PathBuf>, OpenAIError> {
297 create_all_dir(dir.as_ref())?;
298
299 let mut handles = vec![];
300 for id in self.data.clone() {
301 let dir_buf = PathBuf::from(dir.as_ref());
302 handles.push(tokio::spawn(async move { id.save(dir_buf).await }));
303 }
304
305 let results = futures::future::join_all(handles).await;
306 let mut errors = vec![];
307 let mut paths = vec![];
308
309 for result in results {
310 match result {
311 Ok(inner) => match inner {
312 Ok(path) => paths.push(path),
313 Err(e) => errors.push(e),
314 },
315 Err(e) => errors.push(OpenAIError::FileSaveError(e.to_string())),
316 }
317 }
318
319 if errors.is_empty() {
320 Ok(paths)
321 } else {
322 Err(OpenAIError::FileSaveError(
323 errors
324 .into_iter()
325 .map(|e| e.to_string())
326 .collect::<Vec<String>>()
327 .join("; "),
328 ))
329 }
330 }
331}
332
333impl CreateSpeechResponse {
334 pub async fn save<P: AsRef<Path>>(&self, file_path: P) -> Result<(), OpenAIError> {
335 let dir = file_path.as_ref().parent();
336
337 if let Some(dir) = dir {
338 create_all_dir(dir)?;
339 }
340
341 tokio::fs::write(file_path, &self.bytes)
342 .await
343 .map_err(|e| OpenAIError::FileSaveError(e.to_string()))?;
344
345 Ok(())
346 }
347}
348
349impl Image {
350 async fn save<P: AsRef<Path>>(&self, dir: P) -> Result<PathBuf, OpenAIError> {
351 match self {
352 Image::Url { url, .. } => download_url(url, dir).await,
353 Image::B64Json { b64_json, .. } => save_b64(b64_json, dir).await,
354 }
355 }
356}
357
358macro_rules! impl_from_for_integer_array {
359 ($from_typ:ty, $to_typ:ty) => {
360 impl<const N: usize> From<[$from_typ; N]> for $to_typ {
361 fn from(value: [$from_typ; N]) -> Self {
362 Self::IntegerArray(value.to_vec())
363 }
364 }
365
366 impl<const N: usize> From<&[$from_typ; N]> for $to_typ {
367 fn from(value: &[$from_typ; N]) -> Self {
368 Self::IntegerArray(value.to_vec())
369 }
370 }
371
372 impl From<Vec<$from_typ>> for $to_typ {
373 fn from(value: Vec<$from_typ>) -> Self {
374 Self::IntegerArray(value)
375 }
376 }
377
378 impl From<&Vec<$from_typ>> for $to_typ {
379 fn from(value: &Vec<$from_typ>) -> Self {
380 Self::IntegerArray(value.clone())
381 }
382 }
383 };
384}
385
386impl_from_for_integer_array!(u32, EmbeddingInput);
387impl_from_for_integer_array!(u32, Prompt);
388
389macro_rules! impl_from_for_array_of_integer_array {
390 ($from_typ:ty, $to_typ:ty) => {
391 impl From<Vec<Vec<$from_typ>>> for $to_typ {
392 fn from(value: Vec<Vec<$from_typ>>) -> Self {
393 Self::ArrayOfIntegerArray(value)
394 }
395 }
396
397 impl From<&Vec<Vec<$from_typ>>> for $to_typ {
398 fn from(value: &Vec<Vec<$from_typ>>) -> Self {
399 Self::ArrayOfIntegerArray(value.clone())
400 }
401 }
402
403 impl<const M: usize, const N: usize> From<[[$from_typ; N]; M]> for $to_typ {
404 fn from(value: [[$from_typ; N]; M]) -> Self {
405 Self::ArrayOfIntegerArray(value.iter().map(|inner| inner.to_vec()).collect())
406 }
407 }
408
409 impl<const M: usize, const N: usize> From<[&[$from_typ; N]; M]> for $to_typ {
410 fn from(value: [&[$from_typ; N]; M]) -> Self {
411 Self::ArrayOfIntegerArray(value.iter().map(|inner| inner.to_vec()).collect())
412 }
413 }
414
415 impl<const M: usize, const N: usize> From<&[[$from_typ; N]; M]> for $to_typ {
416 fn from(value: &[[$from_typ; N]; M]) -> Self {
417 Self::ArrayOfIntegerArray(value.iter().map(|inner| inner.to_vec()).collect())
418 }
419 }
420
421 impl<const M: usize, const N: usize> From<&[&[$from_typ; N]; M]> for $to_typ {
422 fn from(value: &[&[$from_typ; N]; M]) -> Self {
423 Self::ArrayOfIntegerArray(value.iter().map(|inner| inner.to_vec()).collect())
424 }
425 }
426
427 impl<const N: usize> From<[Vec<$from_typ>; N]> for $to_typ {
428 fn from(value: [Vec<$from_typ>; N]) -> Self {
429 Self::ArrayOfIntegerArray(value.to_vec())
430 }
431 }
432
433 impl<const N: usize> From<&[Vec<$from_typ>; N]> for $to_typ {
434 fn from(value: &[Vec<$from_typ>; N]) -> Self {
435 Self::ArrayOfIntegerArray(value.to_vec())
436 }
437 }
438
439 impl<const N: usize> From<[&Vec<$from_typ>; N]> for $to_typ {
440 fn from(value: [&Vec<$from_typ>; N]) -> Self {
441 Self::ArrayOfIntegerArray(value.into_iter().map(|inner| inner.clone()).collect())
442 }
443 }
444
445 impl<const N: usize> From<&[&Vec<$from_typ>; N]> for $to_typ {
446 fn from(value: &[&Vec<$from_typ>; N]) -> Self {
447 Self::ArrayOfIntegerArray(
448 value
449 .to_vec()
450 .into_iter()
451 .map(|inner| inner.clone())
452 .collect(),
453 )
454 }
455 }
456
457 impl<const N: usize> From<Vec<[$from_typ; N]>> for $to_typ {
458 fn from(value: Vec<[$from_typ; N]>) -> Self {
459 Self::ArrayOfIntegerArray(value.into_iter().map(|inner| inner.to_vec()).collect())
460 }
461 }
462
463 impl<const N: usize> From<&Vec<[$from_typ; N]>> for $to_typ {
464 fn from(value: &Vec<[$from_typ; N]>) -> Self {
465 Self::ArrayOfIntegerArray(value.into_iter().map(|inner| inner.to_vec()).collect())
466 }
467 }
468
469 impl<const N: usize> From<Vec<&[$from_typ; N]>> for $to_typ {
470 fn from(value: Vec<&[$from_typ; N]>) -> Self {
471 Self::ArrayOfIntegerArray(value.into_iter().map(|inner| inner.to_vec()).collect())
472 }
473 }
474
475 impl<const N: usize> From<&Vec<&[$from_typ; N]>> for $to_typ {
476 fn from(value: &Vec<&[$from_typ; N]>) -> Self {
477 Self::ArrayOfIntegerArray(value.into_iter().map(|inner| inner.to_vec()).collect())
478 }
479 }
480 };
481}
482
483impl_from_for_array_of_integer_array!(u32, EmbeddingInput);
484impl_from_for_array_of_integer_array!(u32, Prompt);
485
486impl From<&str> for ChatCompletionFunctionCall {
487 fn from(value: &str) -> Self {
488 match value {
489 "auto" => Self::Auto,
490 "none" => Self::None,
491 _ => Self::Function { name: value.into() },
492 }
493 }
494}
495
496impl From<&str> for FunctionName {
497 fn from(value: &str) -> Self {
498 Self { name: value.into() }
499 }
500}
501
502impl From<String> for FunctionName {
503 fn from(value: String) -> Self {
504 Self { name: value }
505 }
506}
507
508impl From<&str> for ChatCompletionNamedToolChoice {
509 fn from(value: &str) -> Self {
510 Self {
511 r#type: super::ChatCompletionToolType::Function,
512 function: value.into(),
513 }
514 }
515}
516
517impl From<String> for ChatCompletionNamedToolChoice {
518 fn from(value: String) -> Self {
519 Self {
520 r#type: super::ChatCompletionToolType::Function,
521 function: value.into(),
522 }
523 }
524}
525
526impl From<&str> for ChatCompletionToolChoiceOption {
527 fn from(value: &str) -> Self {
528 match value {
529 "auto" => Self::Auto,
530 "none" => Self::None,
531 _ => Self::Named(value.into()),
532 }
533 }
534}
535
536impl From<String> for ChatCompletionToolChoiceOption {
537 fn from(value: String) -> Self {
538 match value.as_str() {
539 "auto" => Self::Auto,
540 "none" => Self::None,
541 _ => Self::Named(value.into()),
542 }
543 }
544}
545
546impl From<(String, serde_json::Value)> for ChatCompletionFunctions {
547 fn from(value: (String, serde_json::Value)) -> Self {
548 Self {
549 name: value.0,
550 description: None,
551 parameters: value.1,
552 }
553 }
554}
555
556impl From<ChatCompletionRequestUserMessage> for ChatCompletionRequestMessage {
559 fn from(value: ChatCompletionRequestUserMessage) -> Self {
560 Self::User(value)
561 }
562}
563
564impl From<ChatCompletionRequestSystemMessage> for ChatCompletionRequestMessage {
565 fn from(value: ChatCompletionRequestSystemMessage) -> Self {
566 Self::System(value)
567 }
568}
569
570impl From<ChatCompletionRequestDeveloperMessage> for ChatCompletionRequestMessage {
571 fn from(value: ChatCompletionRequestDeveloperMessage) -> Self {
572 Self::Developer(value)
573 }
574}
575
576impl From<ChatCompletionRequestAssistantMessage> for ChatCompletionRequestMessage {
577 fn from(value: ChatCompletionRequestAssistantMessage) -> Self {
578 Self::Assistant(value)
579 }
580}
581
582impl From<ChatCompletionRequestFunctionMessage> for ChatCompletionRequestMessage {
583 fn from(value: ChatCompletionRequestFunctionMessage) -> Self {
584 Self::Function(value)
585 }
586}
587
588impl From<ChatCompletionRequestToolMessage> for ChatCompletionRequestMessage {
589 fn from(value: ChatCompletionRequestToolMessage) -> Self {
590 Self::Tool(value)
591 }
592}
593
594impl From<ChatCompletionRequestUserMessageContent> for ChatCompletionRequestUserMessage {
595 fn from(value: ChatCompletionRequestUserMessageContent) -> Self {
596 Self {
597 content: value,
598 name: None,
599 }
600 }
601}
602
603impl From<ChatCompletionRequestSystemMessageContent> for ChatCompletionRequestSystemMessage {
604 fn from(value: ChatCompletionRequestSystemMessageContent) -> Self {
605 Self {
606 content: value,
607 name: None,
608 }
609 }
610}
611
612impl From<ChatCompletionRequestDeveloperMessageContent> for ChatCompletionRequestDeveloperMessage {
613 fn from(value: ChatCompletionRequestDeveloperMessageContent) -> Self {
614 Self {
615 content: value,
616 name: None,
617 }
618 }
619}
620
621impl From<ChatCompletionRequestAssistantMessageContent> for ChatCompletionRequestAssistantMessage {
622 fn from(value: ChatCompletionRequestAssistantMessageContent) -> Self {
623 Self {
624 content: Some(value),
625 ..Default::default()
626 }
627 }
628}
629
630impl From<&str> for ChatCompletionRequestUserMessageContent {
631 fn from(value: &str) -> Self {
632 ChatCompletionRequestUserMessageContent::Text(value.into())
633 }
634}
635
636impl From<String> for ChatCompletionRequestUserMessageContent {
637 fn from(value: String) -> Self {
638 ChatCompletionRequestUserMessageContent::Text(value)
639 }
640}
641
642impl From<&str> for ChatCompletionRequestSystemMessageContent {
643 fn from(value: &str) -> Self {
644 ChatCompletionRequestSystemMessageContent::Text(value.into())
645 }
646}
647
648impl From<String> for ChatCompletionRequestSystemMessageContent {
649 fn from(value: String) -> Self {
650 ChatCompletionRequestSystemMessageContent::Text(value)
651 }
652}
653
654impl From<&str> for ChatCompletionRequestDeveloperMessageContent {
655 fn from(value: &str) -> Self {
656 ChatCompletionRequestDeveloperMessageContent::Text(value.into())
657 }
658}
659
660impl From<String> for ChatCompletionRequestDeveloperMessageContent {
661 fn from(value: String) -> Self {
662 ChatCompletionRequestDeveloperMessageContent::Text(value)
663 }
664}
665
666impl From<&str> for ChatCompletionRequestAssistantMessageContent {
667 fn from(value: &str) -> Self {
668 ChatCompletionRequestAssistantMessageContent::Text(value.into())
669 }
670}
671
672impl From<String> for ChatCompletionRequestAssistantMessageContent {
673 fn from(value: String) -> Self {
674 ChatCompletionRequestAssistantMessageContent::Text(value)
675 }
676}
677
678impl From<&str> for ChatCompletionRequestToolMessageContent {
679 fn from(value: &str) -> Self {
680 ChatCompletionRequestToolMessageContent::Text(value.into())
681 }
682}
683
684impl From<String> for ChatCompletionRequestToolMessageContent {
685 fn from(value: String) -> Self {
686 ChatCompletionRequestToolMessageContent::Text(value)
687 }
688}
689
690impl From<&str> for ChatCompletionRequestUserMessage {
691 fn from(value: &str) -> Self {
692 ChatCompletionRequestUserMessageContent::Text(value.into()).into()
693 }
694}
695
696impl From<String> for ChatCompletionRequestUserMessage {
697 fn from(value: String) -> Self {
698 value.as_str().into()
699 }
700}
701
702impl From<&str> for ChatCompletionRequestSystemMessage {
703 fn from(value: &str) -> Self {
704 ChatCompletionRequestSystemMessageContent::Text(value.into()).into()
705 }
706}
707
708impl From<&str> for ChatCompletionRequestDeveloperMessage {
709 fn from(value: &str) -> Self {
710 ChatCompletionRequestDeveloperMessageContent::Text(value.into()).into()
711 }
712}
713
714impl From<String> for ChatCompletionRequestSystemMessage {
715 fn from(value: String) -> Self {
716 value.as_str().into()
717 }
718}
719
720impl From<String> for ChatCompletionRequestDeveloperMessage {
721 fn from(value: String) -> Self {
722 value.as_str().into()
723 }
724}
725
726impl From<&str> for ChatCompletionRequestAssistantMessage {
727 fn from(value: &str) -> Self {
728 ChatCompletionRequestAssistantMessageContent::Text(value.into()).into()
729 }
730}
731
732impl From<String> for ChatCompletionRequestAssistantMessage {
733 fn from(value: String) -> Self {
734 value.as_str().into()
735 }
736}
737
738impl From<Vec<ChatCompletionRequestUserMessageContentPart>>
739 for ChatCompletionRequestUserMessageContent
740{
741 fn from(value: Vec<ChatCompletionRequestUserMessageContentPart>) -> Self {
742 ChatCompletionRequestUserMessageContent::Array(value)
743 }
744}
745
746impl From<ChatCompletionRequestMessageContentPartText>
747 for ChatCompletionRequestUserMessageContentPart
748{
749 fn from(value: ChatCompletionRequestMessageContentPartText) -> Self {
750 ChatCompletionRequestUserMessageContentPart::Text(value)
751 }
752}
753
754impl From<ChatCompletionRequestMessageContentPartImage>
755 for ChatCompletionRequestUserMessageContentPart
756{
757 fn from(value: ChatCompletionRequestMessageContentPartImage) -> Self {
758 ChatCompletionRequestUserMessageContentPart::ImageUrl(value)
759 }
760}
761
762impl From<ChatCompletionRequestMessageContentPartAudio>
763 for ChatCompletionRequestUserMessageContentPart
764{
765 fn from(value: ChatCompletionRequestMessageContentPartAudio) -> Self {
766 ChatCompletionRequestUserMessageContentPart::InputAudio(value)
767 }
768}
769
770impl From<&str> for ChatCompletionRequestMessageContentPartText {
771 fn from(value: &str) -> Self {
772 ChatCompletionRequestMessageContentPartText { text: value.into() }
773 }
774}
775
776impl From<String> for ChatCompletionRequestMessageContentPartText {
777 fn from(value: String) -> Self {
778 ChatCompletionRequestMessageContentPartText { text: value }
779 }
780}
781
782impl From<&str> for ImageUrl {
783 fn from(value: &str) -> Self {
784 Self {
785 url: value.into(),
786 detail: Default::default(),
787 }
788 }
789}
790
791impl From<String> for ImageUrl {
792 fn from(value: String) -> Self {
793 Self {
794 url: value,
795 detail: Default::default(),
796 }
797 }
798}
799
800impl From<String> for CreateMessageRequestContent {
801 fn from(value: String) -> Self {
802 Self::Content(value)
803 }
804}
805
806impl From<&str> for CreateMessageRequestContent {
807 fn from(value: &str) -> Self {
808 Self::Content(value.to_string())
809 }
810}
811
812impl Default for ChatCompletionRequestUserMessageContent {
813 fn default() -> Self {
814 ChatCompletionRequestUserMessageContent::Text("".into())
815 }
816}
817
818impl Default for CreateMessageRequestContent {
819 fn default() -> Self {
820 Self::Content("".into())
821 }
822}
823
824impl Default for ChatCompletionRequestDeveloperMessageContent {
825 fn default() -> Self {
826 ChatCompletionRequestDeveloperMessageContent::Text("".into())
827 }
828}
829
830impl Default for ChatCompletionRequestSystemMessageContent {
831 fn default() -> Self {
832 ChatCompletionRequestSystemMessageContent::Text("".into())
833 }
834}
835
836impl Default for ChatCompletionRequestToolMessageContent {
837 fn default() -> Self {
838 ChatCompletionRequestToolMessageContent::Text("".into())
839 }
840}
841
842impl AsyncTryFrom<CreateTranscriptionRequest> for reqwest::multipart::Form {
845 type Error = OpenAIError;
846
847 async fn try_from(request: CreateTranscriptionRequest) -> Result<Self, Self::Error> {
848 let audio_part = create_file_part(request.file.source).await?;
849
850 let mut form = reqwest::multipart::Form::new()
851 .part("file", audio_part)
852 .text("model", request.model);
853
854 if let Some(prompt) = request.prompt {
855 form = form.text("prompt", prompt);
856 }
857
858 if let Some(response_format) = request.response_format {
859 form = form.text("response_format", response_format.to_string())
860 }
861
862 if let Some(temperature) = request.temperature {
863 form = form.text("temperature", temperature.to_string())
864 }
865
866 if let Some(language) = request.language {
867 form = form.text("language", language);
868 }
869
870 if let Some(timestamp_granularities) = request.timestamp_granularities {
871 for tg in timestamp_granularities {
872 form = form.text("timestamp_granularities[]", tg.to_string());
873 }
874 }
875
876 Ok(form)
877 }
878}
879
880impl AsyncTryFrom<CreateTranslationRequest> for reqwest::multipart::Form {
881 type Error = OpenAIError;
882
883 async fn try_from(request: CreateTranslationRequest) -> Result<Self, Self::Error> {
884 let audio_part = create_file_part(request.file.source).await?;
885
886 let mut form = reqwest::multipart::Form::new()
887 .part("file", audio_part)
888 .text("model", request.model);
889
890 if let Some(prompt) = request.prompt {
891 form = form.text("prompt", prompt);
892 }
893
894 if let Some(response_format) = request.response_format {
895 form = form.text("response_format", response_format.to_string())
896 }
897
898 if let Some(temperature) = request.temperature {
899 form = form.text("temperature", temperature.to_string())
900 }
901 Ok(form)
902 }
903}
904
905impl AsyncTryFrom<CreateImageEditRequest> for reqwest::multipart::Form {
906 type Error = OpenAIError;
907
908 async fn try_from(request: CreateImageEditRequest) -> Result<Self, Self::Error> {
909 let image_part = create_file_part(request.image.source).await?;
910
911 let mut form = reqwest::multipart::Form::new()
912 .part("image", image_part)
913 .text("prompt", request.prompt);
914
915 if let Some(mask) = request.mask {
916 let mask_part = create_file_part(mask.source).await?;
917 form = form.part("mask", mask_part);
918 }
919
920 if let Some(model) = request.model {
921 form = form.text("model", model.to_string())
922 }
923
924 if request.n.is_some() {
925 form = form.text("n", request.n.unwrap().to_string())
926 }
927
928 if request.size.is_some() {
929 form = form.text("size", request.size.unwrap().to_string())
930 }
931
932 if request.response_format.is_some() {
933 form = form.text(
934 "response_format",
935 request.response_format.unwrap().to_string(),
936 )
937 }
938
939 if request.user.is_some() {
940 form = form.text("user", request.user.unwrap())
941 }
942 Ok(form)
943 }
944}
945
946impl AsyncTryFrom<CreateImageVariationRequest> for reqwest::multipart::Form {
947 type Error = OpenAIError;
948
949 async fn try_from(request: CreateImageVariationRequest) -> Result<Self, Self::Error> {
950 let image_part = create_file_part(request.image.source).await?;
951
952 let mut form = reqwest::multipart::Form::new().part("image", image_part);
953
954 if let Some(model) = request.model {
955 form = form.text("model", model.to_string())
956 }
957
958 if request.n.is_some() {
959 form = form.text("n", request.n.unwrap().to_string())
960 }
961
962 if request.size.is_some() {
963 form = form.text("size", request.size.unwrap().to_string())
964 }
965
966 if request.response_format.is_some() {
967 form = form.text(
968 "response_format",
969 request.response_format.unwrap().to_string(),
970 )
971 }
972
973 if request.user.is_some() {
974 form = form.text("user", request.user.unwrap())
975 }
976 Ok(form)
977 }
978}
979
980impl AsyncTryFrom<CreateFileRequest> for reqwest::multipart::Form {
981 type Error = OpenAIError;
982
983 async fn try_from(request: CreateFileRequest) -> Result<Self, Self::Error> {
984 let file_part = create_file_part(request.file.source).await?;
985 let mut form = reqwest::multipart::Form::new()
986 .part("file", file_part)
987 .text("purpose", request.purpose.to_string());
988
989 if let Some(expires_after) = request.expires_after {
990 form = form.text("expires_after[anchor]", expires_after.anchor.to_string())
991 .text("expires_after[seconds]", expires_after.seconds.to_string());
992 }
993 Ok(form)
994 }
995}
996
997impl AsyncTryFrom<AddUploadPartRequest> for reqwest::multipart::Form {
998 type Error = OpenAIError;
999
1000 async fn try_from(request: AddUploadPartRequest) -> Result<Self, Self::Error> {
1001 let file_part = create_file_part(request.data).await?;
1002 let form = reqwest::multipart::Form::new().part("data", file_part);
1003 Ok(form)
1004 }
1005}
1006
1007impl Default for Input {
1010 fn default() -> Self {
1011 Self::Text("".to_string())
1012 }
1013}
1014
1015impl Default for InputContent {
1016 fn default() -> Self {
1017 Self::TextInput("".to_string())
1018 }
1019}
1020
1021impl From<String> for Input {
1022 fn from(value: String) -> Self {
1023 Input::Text(value)
1024 }
1025}
1026
1027impl From<&str> for Input {
1028 fn from(value: &str) -> Self {
1029 Input::Text(value.to_owned())
1030 }
1031}
1032
1033impl Default for ResponsesRole {
1034 fn default() -> Self {
1035 Self::User
1036 }
1037}
1038
1039impl From<String> for InputContent {
1040 fn from(value: String) -> Self {
1041 Self::TextInput(value)
1042 }
1043}
1044
1045impl From<&str> for InputContent {
1046 fn from(value: &str) -> Self {
1047 Self::TextInput(value.to_owned())
1048 }
1049}
1050
1051impl Default for CodeInterpreterContainer {
1052 fn default() -> Self {
1053 CodeInterpreterContainer::Id("".to_string())
1054 }
1055}