async_openai_wasm/types/
impls.rs

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