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