basic_usage/
basic_usage.rs

1//! Basic usage example of lab-resource-manager
2//!
3//! This example demonstrates how to use the library to monitor
4//! Google Calendar events and send Slack notifications.
5//!
6//! Run with:
7//! ```bash
8//! cargo run --example basic_usage
9//! ```
10
11use lab_resource_manager::{
12    GoogleCalendarUsageRepository, JsonFileIdentityLinkRepository, NotificationRouter,
13    NotifyResourceUsageChangesUseCase, load_config,
14};
15use std::sync::Arc;
16use std::time::Duration;
17
18#[tokio::main]
19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20    println!("🚀 Starting resource usage watcher (basic example)");
21
22    // Load resource configuration
23    let dotenv_path = dotenv::dotenv().ok();
24    let project_root = dotenv_path
25        .as_ref()
26        .and_then(|p| p.parent())
27        .map(|p| p.to_path_buf())
28        .unwrap_or_else(|| std::env::current_dir().expect("Failed to get current directory"));
29
30    let config_path =
31        std::env::var("RESOURCE_CONFIG").unwrap_or_else(|_| "config/resources.toml".to_string());
32    let absolute_config_path = project_root.join(&config_path);
33
34    let config = load_config(
35        absolute_config_path
36            .to_str()
37            .expect("Failed to convert path"),
38    )?;
39    println!("✅ Configuration loaded");
40
41    // Create repository
42    let service_account_key = std::env::var("GOOGLE_SERVICE_ACCOUNT_KEY")
43        .expect("GOOGLE_SERVICE_ACCOUNT_KEY must be set");
44    let absolute_key_path = project_root.join(&service_account_key);
45
46    let repository = GoogleCalendarUsageRepository::new(
47        absolute_key_path.to_str().expect("Failed to convert path"),
48        config.clone(),
49    )
50    .await?;
51    println!("✅ Google Calendar repository initialized");
52
53    // Create identity link repository
54    let identity_links_path = std::env::var("IDENTITY_LINKS_FILE")
55        .map(|p| project_root.join(p))
56        .unwrap_or_else(|_| project_root.join("data/identity_links.json"));
57    let identity_repo = Arc::new(JsonFileIdentityLinkRepository::new(identity_links_path));
58
59    // Create notification router (uses configured notification destinations and identity_repo)
60    let notifier = NotificationRouter::new(config, identity_repo);
61    println!("✅ Notification router initialized (using configured destinations)");
62
63    // Create use case
64    let usecase = NotifyResourceUsageChangesUseCase::new(repository, notifier).await?;
65
66    // Run polling loop
67    let interval = Duration::from_secs(60);
68    println!("🔍 Starting monitoring loop (interval: {:?})", interval);
69    println!("Press Ctrl+C to stop\n");
70
71    loop {
72        match usecase.poll_once().await {
73            Ok(_) => {
74                println!("✅ Poll completed successfully");
75            }
76            Err(e) => {
77                eprintln!("❌ Polling error: {}", e);
78            }
79        }
80
81        tokio::time::sleep(interval).await;
82    }
83}