Skip to main content

gproxy_protocol/wire/gemini/
files.rs

1//! Sources checked 2026-09-13: https://ai.google.dev/api/files and
2//! https://generativelanguage.googleapis.com/$discovery/rest?version=v1beta
3//! revision 20260910; googleapis/python-genai types.py commit
4//! 9052efddccae9f91e699d9b76e0d5a3e032637f5.
5//! ProtoJSON accepts both lowerCamelCase and original snake_case field names.
6use crate::connection::{HttpBody, MultipartPart};
7use crate::{Rest, WireRequest, WireResponse};
8use serde::{Deserialize, Serialize};
9fn present_nullable<'de, D, T>(d: D) -> Result<Option<Option<T>>, D::Error>
10where
11    D: serde::Deserializer<'de>,
12    T: Deserialize<'de>,
13{
14    Option::<T>::deserialize(d).map(Some)
15}
16fn decimal_i64<'de, D: serde::Deserializer<'de>>(d: D) -> Result<String, D::Error> {
17    let s = String::deserialize(d)?;
18    s.parse::<i64>().map_err(serde::de::Error::custom)?;
19    Ok(s)
20}
21/// ProtoJSON int64 values encode as strings; parsers also accept JSON integers.
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
23#[serde(untagged)]
24#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
25#[derive(gproxy_protocol_macros::DeclaredFields)]
26#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
27pub enum FileSize {
28    String(#[serde(deserialize_with = "decimal_i64")] String),
29    Integer(i64),
30}
31
32#[derive(
33    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
34)]
35#[serde(rename_all = "camelCase")]
36#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
37#[derive(gproxy_protocol_macros::DeclaredFields)]
38#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
39pub struct File {
40    #[serde(
41        default,
42        deserialize_with = "present_nullable",
43        skip_serializing_if = "Option::is_none"
44    )]
45    pub name: Option<Option<String>>,
46    #[serde(alias = "display_name")]
47    #[serde(
48        default,
49        deserialize_with = "present_nullable",
50        skip_serializing_if = "Option::is_none"
51    )]
52    pub display_name: Option<Option<String>>,
53    #[serde(alias = "mime_type")]
54    #[serde(
55        default,
56        deserialize_with = "present_nullable",
57        skip_serializing_if = "Option::is_none"
58    )]
59    pub mime_type: Option<Option<String>>,
60    #[serde(alias = "size_bytes")]
61    #[serde(
62        default,
63        deserialize_with = "present_nullable",
64        skip_serializing_if = "Option::is_none"
65    )]
66    pub size_bytes: Option<Option<FileSize>>,
67    #[serde(alias = "create_time")]
68    #[serde(
69        default,
70        deserialize_with = "present_nullable",
71        skip_serializing_if = "Option::is_none"
72    )]
73    pub create_time: Option<Option<String>>,
74    #[serde(alias = "update_time")]
75    #[serde(
76        default,
77        deserialize_with = "present_nullable",
78        skip_serializing_if = "Option::is_none"
79    )]
80    pub update_time: Option<Option<String>>,
81    #[serde(alias = "expiration_time")]
82    #[serde(
83        default,
84        deserialize_with = "present_nullable",
85        skip_serializing_if = "Option::is_none"
86    )]
87    pub expiration_time: Option<Option<String>>,
88    #[serde(alias = "sha256_hash")]
89    #[serde(
90        default,
91        deserialize_with = "present_nullable",
92        skip_serializing_if = "Option::is_none"
93    )]
94    pub sha256_hash: Option<Option<String>>,
95    #[serde(
96        default,
97        deserialize_with = "present_nullable",
98        skip_serializing_if = "Option::is_none"
99    )]
100    pub uri: Option<Option<String>>,
101    #[serde(alias = "download_uri")]
102    #[serde(
103        default,
104        deserialize_with = "present_nullable",
105        skip_serializing_if = "Option::is_none"
106    )]
107    pub download_uri: Option<Option<String>>,
108    #[serde(
109        default,
110        deserialize_with = "present_nullable",
111        skip_serializing_if = "Option::is_none"
112    )]
113    pub state: Option<Option<FileState>>,
114    #[serde(
115        default,
116        deserialize_with = "present_nullable",
117        skip_serializing_if = "Option::is_none"
118    )]
119    pub source: Option<Option<FileSource>>,
120    #[serde(alias = "video_metadata")]
121    #[serde(
122        default,
123        deserialize_with = "present_nullable",
124        skip_serializing_if = "Option::is_none"
125    )]
126    pub video_metadata: Option<Option<VideoFileMetadata>>,
127    #[serde(
128        default,
129        deserialize_with = "present_nullable",
130        skip_serializing_if = "Option::is_none"
131    )]
132    pub error: Option<Option<Status>>,
133    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
134    pub rest: Rest,
135}
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
138#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
139#[derive(gproxy_protocol_macros::DeclaredFields)]
140#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
141pub enum FileState {
142    #[serde(rename = "STATE_UNSPECIFIED")]
143    StateUnspecified,
144    #[serde(rename = "PROCESSING")]
145    Processing,
146    #[serde(rename = "ACTIVE")]
147    Active,
148    #[serde(rename = "FAILED")]
149    Failed,
150}
151
152#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
153#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
154#[derive(gproxy_protocol_macros::DeclaredFields)]
155#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
156pub enum FileSource {
157    #[serde(rename = "SOURCE_UNSPECIFIED")]
158    SourceUnspecified,
159    #[serde(rename = "UPLOADED")]
160    Uploaded,
161    #[serde(rename = "GENERATED")]
162    Generated,
163    #[serde(rename = "REGISTERED")]
164    Registered,
165}
166
167#[derive(
168    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
169)]
170#[serde(rename_all = "camelCase")]
171#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
172#[derive(gproxy_protocol_macros::DeclaredFields)]
173#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
174pub struct VideoFileMetadata {
175    #[serde(alias = "video_duration")]
176    #[serde(
177        default,
178        deserialize_with = "present_nullable",
179        skip_serializing_if = "Option::is_none"
180    )]
181    pub video_duration: Option<Option<String>>,
182    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
183    pub rest: Rest,
184}
185
186#[derive(
187    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
188)]
189#[serde(rename_all = "camelCase")]
190#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
191#[derive(gproxy_protocol_macros::DeclaredFields)]
192#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
193pub struct Status {
194    #[serde(
195        default,
196        deserialize_with = "present_nullable",
197        skip_serializing_if = "Option::is_none"
198    )]
199    pub code: Option<Option<i32>>,
200    #[serde(
201        default,
202        deserialize_with = "present_nullable",
203        skip_serializing_if = "Option::is_none"
204    )]
205    pub message: Option<Option<String>>,
206    #[serde(
207        default,
208        deserialize_with = "present_nullable",
209        skip_serializing_if = "Option::is_none"
210    )]
211    pub details: Option<Option<Vec<StatusDetail>>>,
212    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
213    pub rest: Rest,
214}
215
216/// google.rpc.Status.details is a list of protobuf Any objects. Discovery
217/// explicitly permits arbitrary payload properties; @type identifies their schema.
218#[derive(
219    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
220)]
221#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
222#[derive(gproxy_protocol_macros::DeclaredFields)]
223#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
224pub struct StatusDetail {
225    #[serde(rename = "@type")]
226    pub type_url: String,
227    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
228    pub rest: Rest,
229}
230
231#[derive(
232    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
233)]
234#[serde(rename_all = "camelCase")]
235#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
236#[derive(gproxy_protocol_macros::DeclaredFields)]
237#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
238pub struct ListFilesQuery {
239    #[serde(alias = "page_size")]
240    #[serde(
241        default,
242        deserialize_with = "present_nullable",
243        skip_serializing_if = "Option::is_none"
244    )]
245    pub page_size: Option<Option<i32>>,
246    #[serde(alias = "page_token")]
247    #[serde(
248        default,
249        deserialize_with = "present_nullable",
250        skip_serializing_if = "Option::is_none"
251    )]
252    pub page_token: Option<Option<String>>,
253    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
254    pub rest: Rest,
255}
256
257#[derive(
258    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
259)]
260#[serde(rename_all = "camelCase")]
261#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
262#[derive(gproxy_protocol_macros::DeclaredFields)]
263#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
264pub struct ListFilesResponseBody {
265    #[serde(
266        default,
267        deserialize_with = "present_nullable",
268        skip_serializing_if = "Option::is_none"
269    )]
270    pub files: Option<Option<Vec<File>>>,
271    #[serde(alias = "next_page_token")]
272    #[serde(
273        default,
274        deserialize_with = "present_nullable",
275        skip_serializing_if = "Option::is_none"
276    )]
277    pub next_page_token: Option<Option<String>>,
278    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
279    pub rest: Rest,
280}
281
282#[derive(
283    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
284)]
285#[serde(rename_all = "camelCase")]
286#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
287#[derive(gproxy_protocol_macros::DeclaredFields)]
288#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
289pub struct UploadFileMetadata {
290    #[serde(
291        default,
292        deserialize_with = "present_nullable",
293        skip_serializing_if = "Option::is_none"
294    )]
295    pub file: Option<Option<File>>,
296    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
297    pub rest: Rest,
298}
299
300#[derive(
301    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
302)]
303#[serde(rename_all = "camelCase")]
304#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
305#[derive(gproxy_protocol_macros::DeclaredFields)]
306#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
307pub struct UploadFileResponseBody {
308    #[serde(
309        default,
310        deserialize_with = "present_nullable",
311        skip_serializing_if = "Option::is_none"
312    )]
313    pub file: Option<Option<File>>,
314    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
315    pub rest: Rest,
316}
317
318#[derive(
319    Debug, Clone, PartialEq, Eq, Serialize, Deserialize, gproxy_protocol_macros::WireBuilder,
320)]
321#[serde(rename_all = "camelCase")]
322#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
323#[derive(gproxy_protocol_macros::DeclaredFields)]
324#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
325pub struct DeleteFileResponseBody {
326    #[serde(default, flatten, skip_serializing_if = "serde_json::Map::is_empty")]
327    pub rest: Rest,
328}
329
330#[derive(Debug, gproxy_protocol_macros::WireBuilder)]
331#[cfg_attr(not(feature = "exhaustive"), non_exhaustive)]
332#[derive(gproxy_protocol_macros::DeclaredFields)]
333#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
334pub struct UploadFileForm {
335    pub file: MultipartPart,
336    pub metadata: UploadFileMetadata,
337}
338pub type UploadFileRequest = WireRequest<UploadFileForm>;
339pub type RawUploadFileRequest = WireRequest<crate::connection::Multipart>;
340/// Initial resumable-upload metadata request. Upload session state is transport-owned.
341pub type ResumableUploadRequest = WireRequest<UploadFileMetadata>;
342pub type UploadFileResponse = WireResponse<UploadFileResponseBody>;
343pub type ListFilesRequest = WireRequest<()>;
344pub type ListFilesResponse = WireResponse<ListFilesResponseBody>;
345pub type ListFilesWireResponse = ListFilesResponse;
346pub type RetrieveFileRequest = WireRequest<()>;
347pub type RetrieveFileResponse = WireResponse<File>;
348pub type RetrieveFileContentRequest = WireRequest<()>;
349pub type RetrieveFileContentResponse = WireResponse<HttpBody>;
350pub type DeleteFileRequest = WireRequest<()>;
351pub type DeleteFileResponse = WireResponse<DeleteFileResponseBody>;