openresponses_rust/types/
content.rs1use super::enums::ImageDetail;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5#[serde(tag = "type")]
6pub enum MessageContent {
7 #[serde(rename = "input_text")]
8 InputText { text: String },
9 #[serde(rename = "input_image")]
10 InputImage {
11 #[serde(skip_serializing_if = "Option::is_none")]
12 image_url: Option<String>,
13 #[serde(default)]
14 detail: ImageDetail,
15 },
16 #[serde(rename = "input_file")]
17 InputFile {
18 #[serde(skip_serializing_if = "Option::is_none")]
19 filename: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 file_data: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 file_url: Option<String>,
24 },
25 #[serde(rename = "input_video")]
26 InputVideo { video_url: String },
27 #[serde(rename = "output_text")]
28 OutputText {
29 text: String,
30 #[serde(default)]
31 annotations: Vec<Annotation>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 logprobs: Option<Vec<LogProb>>,
34 },
35 #[serde(rename = "refusal")]
36 Refusal { refusal: String },
37 #[serde(rename = "text")]
38 PlainText { text: String },
39 #[serde(rename = "summary_text")]
40 SummaryText { text: String },
41 #[serde(rename = "reasoning_text")]
42 ReasoningText { text: String },
43}
44
45pub type InputContent = MessageContent;
46pub type OutputContent = MessageContent;
47
48impl MessageContent {
49 pub fn input_text<S: Into<String>>(text: S) -> Self {
50 MessageContent::InputText { text: text.into() }
51 }
52
53 pub fn output_text<S: Into<String>>(text: S) -> Self {
54 MessageContent::OutputText {
55 text: text.into(),
56 annotations: Vec::new(),
57 logprobs: None,
58 }
59 }
60
61 pub fn refusal<S: Into<String>>(text: S) -> Self {
62 MessageContent::Refusal {
63 refusal: text.into(),
64 }
65 }
66
67 pub fn text<S: Into<String>>(text: S) -> Self {
69 Self::input_text(text)
70 }
71
72 pub fn image_url<S: Into<String>>(url: S) -> Self {
73 MessageContent::InputImage {
74 image_url: Some(url.into()),
75 detail: ImageDetail::default(),
76 }
77 }
78
79 pub fn image_url_with_detail<S: Into<String>>(url: S, detail: ImageDetail) -> Self {
80 MessageContent::InputImage {
81 image_url: Some(url.into()),
82 detail,
83 }
84 }
85
86 pub fn file_url<S: Into<String>>(url: S) -> Self {
87 MessageContent::InputFile {
88 filename: None,
89 file_data: None,
90 file_url: Some(url.into()),
91 }
92 }
93
94 pub fn file_data<S: Into<String>>(data: S, filename: Option<String>) -> Self {
95 MessageContent::InputFile {
96 filename,
97 file_data: Some(data.into()),
98 file_url: None,
99 }
100 }
101
102 pub fn video_url<S: Into<String>>(url: S) -> Self {
103 MessageContent::InputVideo {
104 video_url: url.into(),
105 }
106 }
107
108 pub fn summary<S: Into<String>>(text: S) -> Self {
109 MessageContent::SummaryText { text: text.into() }
110 }
111
112 pub fn reasoning<S: Into<String>>(text: S) -> Self {
113 MessageContent::ReasoningText { text: text.into() }
114 }
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
118#[serde(tag = "type")]
119pub enum Annotation {
120 #[serde(rename = "url_citation")]
121 UrlCitation {
122 url: String,
123 title: String,
124 start_index: i32,
125 end_index: i32,
126 },
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
130pub struct LogProb {
131 pub token: String,
132 pub logprob: f64,
133 pub bytes: Vec<u8>,
134 pub top_logprobs: Vec<TopLogProb>,
135}
136
137#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
138pub struct TopLogProb {
139 pub token: String,
140 pub logprob: f64,
141 pub bytes: Vec<u8>,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
145#[serde(untagged)]
146pub enum Content {
147 Part(MessageContent),
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
151#[serde(untagged)]
152pub enum ContentParam {
153 Array(Vec<MessageContent>),
154 Single(String),
155}