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