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!("=== Google Maps Grounding Examples ===\n");
basic_restaurant_recommendations(&gemini).await?;
println!("\n{}\n", "=".repeat(50));
place_specific_question(&gemini).await?;
println!("\n{}\n", "=".repeat(50));
family_friendly_recommendations(&gemini).await?;
println!("\n{}\n", "=".repeat(50));
travel_itinerary_planning(&gemini).await?;
Ok(())
}
async fn basic_restaurant_recommendations(
gemini: &Gemini,
) -> Result<(), Box<dyn std::error::Error>> {
println!("π½οΈ Example 1: Italian Restaurants Within Walking Distance");
let prompt = "What are the best Italian restaurants within a 15-minute walk from here?";
let response = 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(34.050481, -118.248526)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Question: {prompt}\n");
println!("Response: {}", response.text());
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π Sources:");
for chunk in chunks {
if let Some(maps) = &chunk.maps {
println!(" β’ [{}]({})", maps.title, maps.uri);
}
}
}
}
}
Ok(())
}
async fn place_specific_question(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
println!("πͺ Example 2: Cafe with Outdoor Seating");
let prompt = "Is there a cafe near the corner of 1st and Main that has outdoor seating?";
let response = 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(34.050481, -118.248526)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Question: {prompt}\n");
println!("Response: {}", response.text());
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π Sources:");
for chunk in chunks {
if let Some(maps) = &chunk.maps {
println!(" β’ [{}]({})", maps.title, maps.uri);
if let Some(place_id) = &maps.place_id {
println!(" Place ID: {place_id}");
}
}
}
}
if let Some(queries) = &grounding_metadata.web_search_queries {
println!("\nπ Search Queries:");
for query in queries {
println!(" β’ {query}");
}
}
}
}
Ok(())
}
async fn family_friendly_recommendations(
gemini: &Gemini,
) -> Result<(), Box<dyn std::error::Error>> {
println!("π¨βπ©βπ§βπ¦ Example 3: Family-Friendly Restaurants with Playgrounds");
let prompt = "Which family-friendly restaurants near here have the best playground reviews?";
let response = 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(30.2672, -97.7431)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Question: {prompt}\n");
println!("Response: {}", response.text());
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π Sources:");
for (i, chunk) in chunks.iter().enumerate() {
if let Some(maps) = &chunk.maps {
println!(" {}. [{}]({})", i + 1, maps.title, maps.uri);
}
}
}
if let Some(supports) = &grounding_metadata.grounding_supports {
println!("\nπ Grounded Segments:");
for support in supports {
println!(
" β’ \"{}\" -> Sources: {:?}",
support.segment.text.as_deref().unwrap_or(""),
support.grounding_chunk_indices
);
}
}
}
}
Ok(())
}
async fn travel_itinerary_planning(gemini: &Gemini) -> Result<(), Box<dyn std::error::Error>> {
println!("βοΈ Example 4: San Francisco Day Trip Planning");
let prompt = "Plan a day in San Francisco for me. I want to see the Golden Gate Bridge, visit a museum, and have a nice dinner.";
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(37.78193, -122.40476)), }),
function_calling_config: None,
})
.execute()
.await?;
println!("Question: {prompt}\n");
println!("Response: {}", response.text());
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π Sources:");
for (i, chunk) in chunks.iter().enumerate() {
if let Some(maps) = &chunk.maps {
println!(" {}. [{}]({})", i + 1, maps.title, maps.uri);
if let Some(place_id) = &maps.place_id {
println!(" Place ID: {place_id}");
}
}
}
}
if let Some(widget_token) = &grounding_metadata.google_maps_widget_context_token {
println!("\nπΊοΈ Google Maps Widget Context Token:");
println!(
" <gmp-place-contextual context-token=\"{widget_token}\"></gmp-place-contextual>"
);
println!(" \nYou can use this token to render an interactive Google Maps widget in your web application.");
}
if let Some(supports) = &grounding_metadata.grounding_supports {
println!("\nπ Detailed Grounding Information:");
for support in supports {
let segment = &support.segment;
println!(" β’ Text: \"{}\"", segment.text.as_deref().unwrap_or(""));
if let (Some(start), Some(end)) = (segment.start_index, segment.end_index) {
println!(" Location: chars {}-{}", start, end);
}
println!(" Sources: {:?}", support.grounding_chunk_indices);
println!();
}
}
if let Some(queries) = &grounding_metadata.web_search_queries {
println!("π Search Queries Used:");
for query in queries {
println!(" β’ {query}");
}
}
}
}
Ok(())
}