use std::io::Write; use chrono::{DateTime, Utc}; use crate::models::Entry; use crate::error::Result; const ICAL_TIME_FORMAT: &str = "%Y%m%dT%H%M%SZ"; pub fn print_formatted(entries: Vec, out: &mut W, now: DateTime) -> Result<()> { writeln!(out, "BEGIN:VCALENDAR")?; writeln!(out, "CALSCALE:GREGORIAN")?; writeln!(out, "METHOD:PUBLISH")?; writeln!(out, "PRODID:tiempo-rs")?; writeln!(out, "VERSION:2.0")?; let hostname = hostname::get()?; let host = hostname.to_string_lossy(); for entry in entries.into_iter() { let uid = format!("tiempo-{id}", id=entry.id); let note = entry.note.unwrap_or_else(|| "".into()); writeln!(out, "BEGIN:VEVENT")?; writeln!(out, "DESCRIPTION:{note}", note=note)?; writeln!(out, "DTEND:{end}", end=entry.end.unwrap_or(now).format(ICAL_TIME_FORMAT))?; writeln!(out, "DTSTAMP:{start}", start=entry.start.format(ICAL_TIME_FORMAT))?; writeln!(out, "DTSTART:{start}", start=entry.start.format(ICAL_TIME_FORMAT))?; writeln!(out, "SEQUENCE:0")?; writeln!(out, "SUMMARY:{note}", note=note)?; writeln!(out, "UID:{uid}@{host}", uid=uid, host=host)?; writeln!(out, "END:VEVENT")?; } writeln!(out, "END:VCALENDAR")?; Ok(()) } #[cfg(test)] mod tests { use pretty_assertions::assert_eq; use chrono::{Utc, Duration}; use super::*; #[test] fn ical_format() { let now = Utc::now(); let an_hour_ago = now - Duration::hours(1); let half_an_hour_ago = now - Duration::minutes(30); let entries = vec![ Entry::new_sample(1, an_hour_ago, Some(half_an_hour_ago)), Entry::new_sample(2, half_an_hour_ago, None), ]; let mut out = Vec::new(); print_formatted(entries, &mut out, now).unwrap(); let host = hostname::get().unwrap(); let host = host.to_string_lossy(); assert_eq!(&String::from_utf8_lossy(&out), &format!("BEGIN:VCALENDAR CALSCALE:GREGORIAN METHOD:PUBLISH PRODID:tiempo-rs VERSION:2.0 BEGIN:VEVENT DESCRIPTION:entry 1 DTEND:{half_an_hour_ago} DTSTAMP:{an_hour_ago} DTSTART:{an_hour_ago} SEQUENCE:0 SUMMARY:entry 1 UID:tiempo-1@{host} END:VEVENT BEGIN:VEVENT DESCRIPTION:entry 2 DTEND:{now} DTSTAMP:{half_an_hour_ago} DTSTART:{half_an_hour_ago} SEQUENCE:0 SUMMARY:entry 2 UID:tiempo-2@{host} END:VEVENT END:VCALENDAR ", an_hour_ago=an_hour_ago.format(ICAL_TIME_FORMAT), half_an_hour_ago=half_an_hour_ago.format(ICAL_TIME_FORMAT), now=now.format(ICAL_TIME_FORMAT), host=host)); } }