basic_usage/
basic_usage.rs1use 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 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 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 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 let notifier = NotificationRouter::new(config, identity_repo);
61 println!("✅ Notification router initialized (using configured destinations)");
62
63 let usecase = NotifyResourceUsageChangesUseCase::new(repository, notifier).await?;
65
66 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}