async_llm/types/
user_content.rs

1use serde::{Deserialize, Serialize};
2
3use super::{ImageUrl, InputAudio};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6#[serde(untagged)]
7pub enum UserContent {
8    Text(String),
9    Array(Vec<UserContentPart>),
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
13#[serde(tag = "type")]
14#[serde(rename_all = "snake_case")]
15pub enum UserContentPart {
16    Text { text: String },
17    ImageUrl { image_url: ImageUrl },
18    Audio { input_audio: InputAudio },
19}
20
21impl UserContentPart {
22    pub fn image(image_url: impl Into<ImageUrl>) -> Self {
23        Self::ImageUrl {
24            image_url: image_url.into(),
25        }
26    }
27
28    pub fn text(text: impl Into<String>) -> Self {
29        Self::Text { text: text.into() }
30    }
31}
32
33impl Default for UserContent {
34    fn default() -> Self {
35        Self::Text("".into())
36    }
37}
38
39impl From<&str> for UserContent {
40    fn from(value: &str) -> Self {
41        Self::Text(value.into())
42    }
43}
44
45impl From<&str> for UserContentPart {
46    fn from(value: &str) -> Self {
47        Self::text(value)
48    }
49}
50
51impl From<String> for UserContentPart {
52    fn from(value: String) -> Self {
53        Self::text(value)
54    }
55}
56
57impl From<Vec<&str>> for UserContent {
58    fn from(value: Vec<&str>) -> Self {
59        Self::Array(
60            value
61                .into_iter()
62                .map(|v| UserContentPart::Text {
63                    text: v.to_string(),
64                })
65                .collect(),
66        )
67    }
68}