use gemini_rust::prelude::*;
use gemini_rust::{LatLng, RetrievalConfig, Tool, ToolConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let gemini = Gemini::pro(std::env::var("GEMINI_API_KEY")?)?;
println!("đ§ Advanced Google Maps Configuration Example\n");
manual_tool_configuration(&gemini).await?;
println!("\n{}\n", "=".repeat(60));
widget_enabled_grounding(&gemini).await?;
println!("\n{}\n", "=".repeat(60));
location_comparison(&gemini).await?;
Ok(())
}
async fn manual_tool_configuration(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
println!("đ Example 1: Manual Tool Configuration");
let prompt = "Find me vegan restaurants within a 10-minute drive.";
let tool = Tool::google_maps(None); let tool_config = ToolConfig {
retrieval_config: Some(RetrievalConfig {
lat_lng: Some(LatLng::new(40.7128, -74.0060)), }),
function_calling_config: None,
};
let response = gemini
.generate_content()
.with_user_message(prompt)
.with_tool(tool)
.with_tool_config(tool_config)
.execute()
.await?;
println!("Query: {prompt}\n");
println!("Response: {}", response.text());
display_grounding_info(&response);
Ok(())
}
async fn widget_enabled_grounding(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
println!("đēī¸ Example 2: Widget-Enabled Grounding");
let prompt = "Plan a food tour of downtown Chicago. Include 3-4 different types of cuisine.";
let response = gemini
.generate_content()
.with_user_message(prompt)
.with_tool(Tool::google_maps(Some(true))) .with_tool_config(ToolConfig {
retrieval_config: Some(RetrievalConfig {
lat_lng: Some(LatLng::new(41.8781, -87.6298)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Query: {prompt}\n");
println!("Response: {}", response.text());
display_grounding_info(&response);
if let Some(candidate) = response.candidates.first() {
if let Some(grounding_metadata) = &candidate.grounding_metadata {
if let Some(widget_token) = &grounding_metadata.google_maps_widget_context_token {
println!("\nđ¯ Widget Context Token Available:");
println!(
" Token: {}...",
&widget_token[..50.min(widget_token.len())]
);
println!(" Use this token to render an interactive Google Maps widget:");
println!(
" <gmp-place-contextual context-token=\"{widget_token}\"></gmp-place-contextual>"
);
} else {
println!("\nâšī¸ No widget context token in this response.");
}
}
}
Ok(())
}
async fn location_comparison(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
println!("đ Example 3: Location Context Comparison");
let prompt = "What are some popular brunch spots?";
println!("â WITHOUT location context:");
let response_no_location = gemini
.generate_content()
.with_user_message(prompt)
.execute()
.await?;
println!("Response: {}", response_no_location.text());
check_for_grounding(&response_no_location);
println!("\n---\n");
println!("â
WITH location context (Seattle):");
let response_with_location = gemini
.generate_content()
.with_user_message(prompt)
.with_tool(Tool::google_maps(None)) .with_tool_config(ToolConfig {
retrieval_config: Some(RetrievalConfig {
lat_lng: Some(LatLng::new(47.6062, -122.3321)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Response: {}", response_with_location.text());
check_for_grounding(&response_with_location);
Ok(())
}
fn display_grounding_info(response: &GenerationResponse) {
if let Some(candidate) = response.candidates.first() {
if let Some(grounding_metadata) = &candidate.grounding_metadata {
if let Some(chunks) = &grounding_metadata.grounding_chunks {
println!("\nđ Grounding Sources:");
for (i, chunk) in chunks.iter().enumerate() {
if let Some(maps) = &chunk.maps {
println!(" {}. {} - {}", i + 1, maps.title, maps.uri);
} else if let Some(web) = &chunk.web {
println!(" {}. {} - {}", i + 1, web.title, web.uri);
}
}
}
if let Some(supports) = &grounding_metadata.grounding_supports {
println!("\nđ Grounding Supports:");
for support in supports {
println!(
" âĸ \"{}\" -> {:?}",
support.segment.text.as_deref().unwrap_or(""),
support.grounding_chunk_indices
);
}
}
if let Some(queries) = &grounding_metadata.web_search_queries {
println!("\nđ Search Queries:");
for query in queries {
println!(" âĸ {query}");
}
}
} else {
println!("\nâšī¸ No grounding metadata available.");
}
}
}
fn check_for_grounding(response: &GenerationResponse) {
if let Some(candidate) = response.candidates.first() {
if let Some(grounding_metadata) = &candidate.grounding_metadata {
if let Some(chunks) = &grounding_metadata.grounding_chunks {
println!(" â
Grounded with {} source(s)", chunks.len());
} else {
println!(" â No grounding sources");
}
} else {
println!(" â No grounding metadata");
}
} else {
println!(" â No candidates in response");
}
}