outfox_openai/spec/
text.rs

1use std::fmt::{self, Display};
2use std::ops::Deref;
3
4use serde::{Deserialize, Serialize};
5
6#[derive(Default, Debug, Deserialize, Clone, PartialEq, Serialize)]
7pub struct TextObject {
8    pub text: String,
9}
10
11impl From<&str> for TextObject {
12    fn from(value: &str) -> Self {
13        TextObject { text: value.into() }
14    }
15}
16
17impl From<String> for TextObject {
18    fn from(value: String) -> Self {
19        TextObject { text: value }
20    }
21}
22
23impl Display for TextObject {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "{}", self.text)
26    }
27}
28
29impl Deref for TextObject {
30    type Target = str;
31
32    fn deref(&self) -> &Self::Target {
33        &self.text
34    }
35}
36
37impl AsRef<String> for TextObject {
38    fn as_ref(&self) -> &String {
39        &self.text
40    }
41}
42impl AsRef<str> for TextObject {
43    fn as_ref(&self) -> &str {
44        &self.text
45    }
46}
47
48#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
49#[serde(untagged)]
50pub enum PartibleTextContent {
51    /// The text contents of the message.
52    Text(String),
53    /// An array of content parts with a defined type. Supported options differ based on the [model](https://platform.openai.com/docs/models) being used to generate the response. Can contain text, image, or audio inputs.
54    Array(Vec<TextObject>),
55}
56impl PartibleTextContent {
57    pub fn to_texts(&self) -> Vec<String> {
58        match self {
59            Self::Text(text) => vec![text.clone()],
60            Self::Array(parts) => parts.iter().map(|p| p.to_string()).collect(),
61        }
62    }
63    pub fn into_texts(self) -> Vec<String> {
64        match self {
65            Self::Text(text) => vec![text],
66            Self::Array(parts) => parts.into_iter().map(|p| p.to_string()).collect(),
67        }
68    }
69    pub fn is_empty(&self) -> bool {
70        match self {
71            Self::Text(text) => text.is_empty(),
72            Self::Array(parts) => parts.is_empty(),
73        }
74    }
75}
76impl Display for PartibleTextContent {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        match self {
79            Self::Text(text) => write!(f, "{text}"),
80            Self::Array(parts) => write!(
81                f,
82                "{}",
83                parts
84                    .iter()
85                    .map(|p| &*p.text)
86                    .collect::<Vec<_>>()
87                    .join("\n")
88            ),
89        }
90    }
91}
92impl From<&str> for PartibleTextContent {
93    fn from(value: &str) -> Self {
94        Self::Text(value.into())
95    }
96}
97
98impl From<String> for PartibleTextContent {
99    fn from(value: String) -> Self {
100        Self::Text(value)
101    }
102}
103impl Default for PartibleTextContent {
104    fn default() -> Self {
105        Self::Text("".into())
106    }
107}
108
109#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
110#[serde(tag = "type")]
111#[serde(rename_all = "snake_case")]
112pub enum UnitaryTextContent {
113    Text(TextObject),
114}
115impl Display for UnitaryTextContent {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        match self {
118            Self::Text(text) => write!(f, "{text}"),
119        }
120    }
121}
122impl From<&str> for UnitaryTextContent {
123    fn from(value: &str) -> Self {
124        Self::Text(value.into())
125    }
126}
127
128impl From<String> for UnitaryTextContent {
129    fn from(value: String) -> Self {
130        Self::Text(value.into())
131    }
132}
133impl From<TextObject> for UnitaryTextContent {
134    fn from(value: TextObject) -> Self {
135        Self::Text(value)
136    }
137}
138impl Default for UnitaryTextContent {
139    fn default() -> Self {
140        Self::Text("".into())
141    }
142}