Skip to main content

openai_types/file/
manual.rs

1// Hand-crafted file types for openai-types.
2// These types mirror the original src/types/file.rs but are standalone (no crate:: imports).
3
4use serde::{Deserialize, Serialize};
5
6/// Helper to serialize a bare String value (used by the Other variant).
7#[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
15/// Helper function to serialize the `Other(String)` variant.
16pub 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/// The intended purpose of an uploaded file.
24#[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    /// Catch-all for unknown purposes (forward compatibility).
44    #[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/// Processing status of an uploaded file.
69#[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/// A file object from the API.
82#[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/// Response from listing files.
98#[derive(Debug, Clone, Deserialize)]
99pub struct FileList {
100    pub object: String,
101    pub data: Vec<FileObject>,
102    /// Whether there are more results available.
103    #[serde(default)]
104    pub has_more: Option<bool>,
105    /// ID of the first object in the list.
106    #[serde(default)]
107    pub first_id: Option<String>,
108    /// ID of the last object in the list.
109    #[serde(default)]
110    pub last_id: Option<String>,
111}
112
113/// Response from deleting a file.
114#[derive(Debug, Clone, Deserialize)]
115pub struct FileDeleted {
116    pub id: String,
117    pub deleted: bool,
118    pub object: String,
119}
120
121/// Parameters for file upload (multipart).
122#[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/// Parameters for listing files with pagination.
140#[derive(Debug, Clone, Default)]
141pub struct FileListParams {
142    /// Cursor for pagination -- fetch results after this file ID.
143    pub after: Option<String>,
144    /// Maximum number of results per page (1-10000).
145    pub limit: Option<i64>,
146    /// Sort order by `created_at`.
147    pub order: Option<String>,
148    /// Filter by file purpose.
149    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    /// Convert to query parameter pairs for the HTTP request.
178    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}