Skip to main content

gemini_client_api/gemini/utils/
macros.rs

1use serde_json::{Value, json};
2
3/// Trait for types that can generate a Gemini-compatible JSON schema.
4pub trait GeminiSchema {
5    fn gemini_schema() -> Value;
6    /// Returns none if schema is of primitive type or name not provided.
7    fn name(gemini_schema: &Value) -> Option<&str> {
8        gemini_schema["name"].as_str()
9    }
10}
11
12macro_rules! impl_primitive {
13    ($ty:ty, $schema_type:expr) => {
14        impl GeminiSchema for $ty {
15            fn gemini_schema() -> Value {
16                json!({ "type": $schema_type })
17            }
18        }
19    };
20}
21
22impl_primitive!(String, "STRING");
23impl_primitive!(bool, "BOOLEAN");
24impl_primitive!(f32, "NUMBER");
25impl_primitive!(f64, "NUMBER");
26impl_primitive!(i8, "INTEGER");
27impl_primitive!(i16, "INTEGER");
28impl_primitive!(i32, "INTEGER");
29impl_primitive!(i64, "INTEGER");
30impl_primitive!(i128, "INTEGER");
31impl_primitive!(isize, "INTEGER");
32impl_primitive!(u8, "INTEGER");
33impl_primitive!(u16, "INTEGER");
34impl_primitive!(u32, "INTEGER");
35impl_primitive!(u64, "INTEGER");
36impl_primitive!(u128, "INTEGER");
37impl_primitive!(usize, "INTEGER");
38
39impl GeminiSchema for &str {
40    fn gemini_schema() -> Value {
41        json!({ "type": "STRING" })
42    }
43}
44
45impl<T: GeminiSchema> GeminiSchema for Vec<T> {
46    fn gemini_schema() -> Value {
47        json!({
48            "type": "ARRAY",
49            "items": T::gemini_schema()
50        })
51    }
52}
53
54impl<T: GeminiSchema> GeminiSchema for Option<T> {
55    fn gemini_schema() -> Value {
56        let mut schema = T::gemini_schema();
57        if let Some(obj) = schema.as_object_mut() {
58            obj.insert("nullable".to_string(), json!(true));
59        }
60        schema
61    }
62}