1use serde::{Deserialize, Serialize};
5
6#[allow(clippy::ptr_arg)]
8fn serialize_other_string<S>(value: &String, serializer: S) -> Result<S::Ok, S::Error>
9where
10 S: serde::Serializer,
11{
12 serialize_other(value, serializer)
13}
14
15pub fn serialize_other<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
17where
18 S: serde::Serializer,
19{
20 serializer.serialize_str(value)
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
25#[non_exhaustive]
26pub enum FilePurpose {
27 #[serde(rename = "assistants")]
28 Assistants,
29 #[serde(rename = "assistants_output")]
30 AssistantsOutput,
31 #[serde(rename = "batch")]
32 Batch,
33 #[serde(rename = "batch_output")]
34 BatchOutput,
35 #[serde(rename = "fine-tune")]
36 FineTune,
37 #[serde(rename = "fine-tune-results")]
38 FineTuneResults,
39 #[serde(rename = "vision")]
40 Vision,
41 #[serde(rename = "user_data")]
42 UserData,
43 #[serde(serialize_with = "serialize_other_string")]
45 Other(String),
46}
47
48impl<'de> Deserialize<'de> for FilePurpose {
49 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50 where
51 D: serde::Deserializer<'de>,
52 {
53 let s = String::deserialize(deserializer)?;
54 match s.as_str() {
55 "assistants" => Ok(FilePurpose::Assistants),
56 "assistants_output" => Ok(FilePurpose::AssistantsOutput),
57 "batch" => Ok(FilePurpose::Batch),
58 "batch_output" => Ok(FilePurpose::BatchOutput),
59 "fine-tune" => Ok(FilePurpose::FineTune),
60 "fine-tune-results" => Ok(FilePurpose::FineTuneResults),
61 "vision" => Ok(FilePurpose::Vision),
62 "user_data" => Ok(FilePurpose::UserData),
63 _ => Ok(FilePurpose::Other(s)),
64 }
65 }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
70#[cfg_attr(feature = "structured", derive(schemars::JsonSchema))]
71#[non_exhaustive]
72pub enum FileStatus {
73 #[serde(rename = "uploaded")]
74 Uploaded,
75 #[serde(rename = "processed")]
76 Processed,
77 #[serde(rename = "error")]
78 Error,
79}
80
81#[derive(Debug, Clone, Deserialize)]
83pub struct FileObject {
84 pub id: String,
85 pub bytes: i64,
86 pub created_at: i64,
87 pub filename: String,
88 pub object: String,
89 pub purpose: FilePurpose,
90 pub status: FileStatus,
91 #[serde(default)]
92 pub status_details: Option<String>,
93 #[serde(default)]
94 pub expires_at: Option<i64>,
95}
96
97#[derive(Debug, Clone, Deserialize)]
99pub struct FileList {
100 pub object: String,
101 pub data: Vec<FileObject>,
102 #[serde(default)]
104 pub has_more: Option<bool>,
105 #[serde(default)]
107 pub first_id: Option<String>,
108 #[serde(default)]
110 pub last_id: Option<String>,
111}
112
113#[derive(Debug, Clone, Deserialize)]
115pub struct FileDeleted {
116 pub id: String,
117 pub deleted: bool,
118 pub object: String,
119}
120
121#[derive(Debug)]
123pub struct FileUploadParams {
124 pub file: Vec<u8>,
125 pub filename: String,
126 pub purpose: FilePurpose,
127}
128
129impl FileUploadParams {
130 pub fn new(file: Vec<u8>, filename: impl Into<String>, purpose: FilePurpose) -> Self {
131 Self {
132 file,
133 filename: filename.into(),
134 purpose,
135 }
136 }
137}
138
139#[derive(Debug, Clone, Default)]
141pub struct FileListParams {
142 pub after: Option<String>,
144 pub limit: Option<i64>,
146 pub order: Option<String>,
148 pub purpose: Option<FilePurpose>,
150}
151
152impl FileListParams {
153 pub fn new() -> Self {
154 Self::default()
155 }
156
157 pub fn after(mut self, after: impl Into<String>) -> Self {
158 self.after = Some(after.into());
159 self
160 }
161
162 pub fn limit(mut self, limit: i64) -> Self {
163 self.limit = Some(limit);
164 self
165 }
166
167 pub fn order(mut self, order: impl Into<String>) -> Self {
168 self.order = Some(order.into());
169 self
170 }
171
172 pub fn purpose(mut self, purpose: FilePurpose) -> Self {
173 self.purpose = Some(purpose);
174 self
175 }
176
177 pub fn to_query(&self) -> Vec<(String, String)> {
179 let mut q = Vec::new();
180 if let Some(ref after) = self.after {
181 q.push(("after".into(), after.clone()));
182 }
183 if let Some(limit) = self.limit {
184 q.push(("limit".into(), limit.to_string()));
185 }
186 if let Some(ref order) = self.order {
187 q.push(("order".into(), order.clone()));
188 }
189 if let Some(ref purpose) = self.purpose {
190 q.push((
191 "purpose".into(),
192 serde_json::to_value(purpose)
193 .unwrap()
194 .as_str()
195 .unwrap()
196 .to_string(),
197 ));
198 }
199 q
200 }
201}