use { anyhow::{ Result, anyhow, }, std::env::args, }; struct CrateKaldav { client: kaldav::Client, } impl CrateKaldav { fn new(url: &str, username: String, password: Option) -> Self { println!("kaldav"); let mut client = kaldav::Client::new(url); client.set_auth(Some(kaldav::Authorization { username, password, })); Self { client, } } fn show_content(&self) -> Result<()> { // This function does not do what we want, because Principal::home() does not appear to // work in our environment. // Reading https://datatracker.ietf.org/doc/html/rfc4791#section-6.2.1 reveals that the // CALDAV:calendar-home-set property merely SHOULD, rather than MUST, be implemented. let principals = self.client.principals()?; // eprintln!("Principals: {principals:?}"); let mut home = None; println!("Attempting to find home."); for p in principals { home = p.home().ok(); if home.is_some() { break; } } if home.is_some() { println!("Found home: {home:?}"); } else { return Err(anyhow!("No home found in any Principal. :(")); } // This function is heavily based on: // https://github.com/sanpii/kaldav/blob/main/examples/list_events.rs eprintln!("Retrieving list of calendars."); let calendars = self.client.calendars()?; for (name, calendar) in calendars { println!("Calendar '{}'", name); let objects = calendar.events()?; if objects.is_empty() { println!(" no events"); continue; } for object in objects { for event in object.events { println!( " {} - {}", event.dtstart, event.summary.unwrap_or_default() ); } } } Ok(()) } } fn main() -> Result<()> { let caldav_url = args().nth(1).expect("Missing caldav url argument."); let username = args().nth(2).expect("Missing username argument."); let password = args().nth(3).expect("Missing password argument."); let kaldav = CrateKaldav::new(&caldav_url, username.clone(), Some(password.clone())); kaldav.show_content()?; Ok(()) }