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