Skip to main content

gproxy_protocol/gemini/
types.rs

1use std::collections::BTreeMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// HTTP method used by generated request descriptors.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8#[serde(rename_all = "UPPERCASE")]
9pub enum HttpMethod {
10    Get,
11    Post,
12    Put,
13    Patch,
14    Delete,
15}
16
17/// Shared JSON object map for unknown/dynamic fields.
18pub type JsonObject = BTreeMap<String, Value>;
19
20/// Common response headers returned by Gemini endpoints.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
22pub struct GeminiResponseHeaders {
23    /// Additional response headers.
24    #[serde(flatten, default, skip_serializing_if = "BTreeMap::is_empty")]
25    pub extra: BTreeMap<String, String>,
26}
27
28/// Serde helpers for `http::StatusCode` as numeric code (e.g. 200, 400).
29pub mod status_code_serde {
30    use http::StatusCode;
31    use serde::de::Error as _;
32    use serde::{Deserialize, Deserializer, Serializer};
33
34    pub fn serialize<S>(value: &StatusCode, serializer: S) -> Result<S::Ok, S::Error>
35    where
36        S: Serializer,
37    {
38        serializer.serialize_u16(value.as_u16())
39    }
40
41    pub fn deserialize<'de, D>(deserializer: D) -> Result<StatusCode, D::Error>
42    where
43        D: Deserializer<'de>,
44    {
45        let code = u16::deserialize(deserializer)?;
46        StatusCode::from_u16(code).map_err(D::Error::custom)
47    }
48}
49
50/// Information about a Gemini model.
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52pub struct GeminiModelInfo {
53    /// Resource name of the model, e.g. `models/gemini-2.0-flash`.
54    pub name: String,
55    /// Base model id, e.g. `gemini-2.0-flash`.
56    #[serde(
57        rename = "baseModelId",
58        default,
59        skip_serializing_if = "Option::is_none"
60    )]
61    pub base_model_id: Option<String>,
62    /// Major version string, e.g. `2.0`.
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub version: Option<String>,
65    /// Human-readable model name.
66    #[serde(
67        rename = "displayName",
68        default,
69        skip_serializing_if = "Option::is_none"
70    )]
71    pub display_name: Option<String>,
72    /// Short description.
73    #[serde(default, skip_serializing_if = "Option::is_none")]
74    pub description: Option<String>,
75    /// Maximum number of input tokens allowed.
76    #[serde(
77        rename = "inputTokenLimit",
78        default,
79        skip_serializing_if = "Option::is_none"
80    )]
81    pub input_token_limit: Option<u64>,
82    /// Maximum number of output tokens allowed.
83    #[serde(
84        rename = "outputTokenLimit",
85        default,
86        skip_serializing_if = "Option::is_none"
87    )]
88    pub output_token_limit: Option<u64>,
89    /// Supported generation methods.
90    #[serde(
91        rename = "supportedGenerationMethods",
92        default,
93        skip_serializing_if = "Option::is_none"
94    )]
95    pub supported_generation_methods: Option<Vec<String>>,
96    /// Whether this model supports thinking.
97    #[serde(default, skip_serializing_if = "Option::is_none")]
98    pub thinking: Option<bool>,
99    /// Default temperature.
100    #[serde(default, skip_serializing_if = "Option::is_none")]
101    pub temperature: Option<f64>,
102    /// Maximum temperature.
103    #[serde(
104        rename = "maxTemperature",
105        default,
106        skip_serializing_if = "Option::is_none"
107    )]
108    pub max_temperature: Option<f64>,
109    /// Default nucleus sampling threshold.
110    #[serde(rename = "topP", default, skip_serializing_if = "Option::is_none")]
111    pub top_p: Option<f64>,
112    /// Default top-k value.
113    #[serde(rename = "topK", default, skip_serializing_if = "Option::is_none")]
114    pub top_k: Option<u64>,
115}
116
117/// Google API style error envelope.
118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
119pub struct GeminiApiErrorResponse {
120    pub error: GeminiApiError,
121}
122
123/// Google API style error object.
124#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
125pub struct GeminiApiError {
126    /// Numeric HTTP-like status code.
127    pub code: i32,
128    /// Human-readable error message.
129    pub message: String,
130    /// String status code such as `INVALID_ARGUMENT`.
131    #[serde(default, skip_serializing_if = "Option::is_none")]
132    pub status: Option<String>,
133    /// Optional structured details.
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub details: Option<Vec<JsonObject>>,
136}