Skip to main content

openresponses_rust/types/
items.rs

1use super::{content::*, enums::*};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
5#[serde(tag = "type")]
6pub enum Item {
7    #[serde(rename = "message")]
8    Message {
9        #[serde(skip_serializing_if = "Option::is_none")]
10        id: Option<String>,
11        #[serde(skip_serializing_if = "Option::is_none")]
12        status: Option<MessageStatus>,
13        role: MessageRole,
14        #[serde(with = "content_serde")]
15        content: Vec<OutputContent>,
16    },
17    #[serde(rename = "function_call")]
18    FunctionCall {
19        #[serde(skip_serializing_if = "Option::is_none")]
20        id: Option<String>,
21        call_id: String,
22        name: String,
23        arguments: String,
24        status: FunctionCallStatus,
25    },
26    #[serde(rename = "function_call_output")]
27    FunctionCallOutput {
28        #[serde(skip_serializing_if = "Option::is_none")]
29        id: Option<String>,
30        call_id: String,
31        #[serde(with = "output_serde")]
32        output: FunctionOutput,
33        status: FunctionCallOutputStatus,
34    },
35    #[serde(rename = "reasoning")]
36    Reasoning {
37        #[serde(skip_serializing_if = "Option::is_none")]
38        id: Option<String>,
39        #[serde(skip_serializing_if = "Option::is_none")]
40        content: Option<Vec<InputContent>>,
41        summary: Vec<InputContent>,
42        #[serde(skip_serializing_if = "Option::is_none")]
43        encrypted_content: Option<String>,
44    },
45    #[serde(rename = "item_reference")]
46    ItemReference { id: String },
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
50#[serde(untagged)]
51pub enum FunctionOutput {
52    Text(String),
53    Content(Vec<InputContent>),
54}
55
56impl Item {
57    pub fn user_message<S: Into<String>>(content: S) -> Self {
58        Item::Message {
59            id: None,
60            status: None,
61            role: MessageRole::User,
62            content: vec![OutputContent::text(content)],
63        }
64    }
65
66    pub fn user_message_with_content(content: Vec<OutputContent>) -> Self {
67        Item::Message {
68            id: None,
69            status: None,
70            role: MessageRole::User,
71            content,
72        }
73    }
74
75    pub fn assistant_message<S: Into<String>>(content: S) -> Self {
76        Item::Message {
77            id: None,
78            status: None,
79            role: MessageRole::Assistant,
80            content: vec![OutputContent::text(content)],
81        }
82    }
83
84    pub fn system_message<S: Into<String>>(content: S) -> Self {
85        Item::Message {
86            id: None,
87            status: None,
88            role: MessageRole::System,
89            content: vec![OutputContent::text(content)],
90        }
91    }
92
93    pub fn developer_message<S: Into<String>>(content: S) -> Self {
94        Item::Message {
95            id: None,
96            status: None,
97            role: MessageRole::Developer,
98            content: vec![OutputContent::text(content)],
99        }
100    }
101
102    pub fn reference<S: Into<String>>(id: S) -> Self {
103        Item::ItemReference { id: id.into() }
104    }
105}
106
107mod content_serde {
108    use super::*;
109    use serde::{Deserialize, Deserializer, Serialize, Serializer};
110
111    pub fn serialize<S: Serializer>(
112        content: &Vec<OutputContent>,
113        serializer: S,
114    ) -> Result<S::Ok, S::Error> {
115        content.serialize(serializer)
116    }
117
118    pub fn deserialize<'de, D: Deserializer<'de>>(
119        deserializer: D,
120    ) -> Result<Vec<OutputContent>, D::Error> {
121        let content = Deserialize::deserialize(deserializer)?;
122        Ok(content)
123    }
124}
125
126mod output_serde {
127    use super::*;
128    use serde::{Deserialize, Deserializer, Serialize, Serializer};
129
130    pub fn serialize<S: Serializer>(
131        output: &FunctionOutput,
132        serializer: S,
133    ) -> Result<S::Ok, S::Error> {
134        match output {
135            FunctionOutput::Text(s) => serializer.serialize_str(s),
136            FunctionOutput::Content(c) => c.serialize(serializer),
137        }
138    }
139
140    pub fn deserialize<'de, D: Deserializer<'de>>(
141        deserializer: D,
142    ) -> Result<FunctionOutput, D::Error> {
143        let value = serde_json::Value::deserialize(deserializer)?;
144
145        if let Some(s) = value.as_str() {
146            return Ok(FunctionOutput::Text(s.to_string()));
147        }
148
149        if let Ok(contents) = serde_json::from_value::<Vec<InputContent>>(value.clone()) {
150            return Ok(FunctionOutput::Content(contents));
151        }
152
153        Err(serde::de::Error::custom("Invalid function output format"))
154    }
155}