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