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