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