#[cfg(test)]
mod hashmap_tests {
use rstructor::{GeminiClient, GeminiModel, Instructor, LLMClient};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::env;
#[derive(Instructor, Serialize, Deserialize, Debug)]
struct Inventory {
#[llm(description = "Map of category names to list of items in that category")]
categories: HashMap<String, Vec<String>>,
#[llm(description = "Map of item names to their current stock count")]
stock_counts: HashMap<String, u32>,
}
#[derive(Instructor, Serialize, Deserialize, Debug)]
struct Metadata {
pub score: f32,
pub tags: Vec<String>,
}
#[derive(Instructor, Serialize, Deserialize, Debug)]
struct ComplexMap {
#[llm(description = "Map of user IDs to their metadata objects")]
user_data: HashMap<String, Metadata>,
}
#[tokio::test]
async fn test_gemini_hashmap_nested_vec() {
let api_key = env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY must be set");
let client = GeminiClient::new(api_key)
.unwrap()
.model(GeminiModel::Gemini31ProPreview)
.temperature(0.0)
.no_retries();
let prompt = "Organize these items into categories: apple, hammer, banana, screwdriver, drill. Use category names like 'fruit', 'tools' as the keys.";
let result: rstructor::Result<Inventory> = client.materialize(prompt).await;
assert!(
result.is_ok(),
"HashMap<String, Vec<String>> failed: {:?}",
result.err()
);
let inv = result.unwrap();
assert!(
!inv.categories.is_empty(),
"Expected categories to have entries, got empty map"
);
assert!(
inv.categories.values().any(|v| !v.is_empty()),
"Expected at least one category to have items"
);
}
#[tokio::test]
async fn test_gemini_hashmap_complex_value() {
let api_key = env::var("GEMINI_API_KEY").expect("GEMINI_API_KEY must be set");
let client = GeminiClient::new(api_key)
.unwrap()
.model(GeminiModel::Gemini31ProPreview)
.temperature(0.0)
.no_retries();
let prompt = "Generate metadata for users. Create entries with keys 'alice' and 'bob'. Alice has score 9.5 and tags 'pro', 'admin'. Bob has score 4.0 and tag 'newbie'.";
let result: rstructor::Result<ComplexMap> = client.materialize(prompt).await;
assert!(
result.is_ok(),
"HashMap<String, Metadata> failed: {:?}",
result.err()
);
let map = result.unwrap();
assert!(
!map.user_data.is_empty(),
"Expected user_data to have entries, got empty map"
);
for (key, metadata) in &map.user_data {
assert!(
metadata.score >= 0.0,
"Expected valid score for key '{}', got {}",
key,
metadata.score
);
}
}
}