tiempo-rs/src/formatters/ical.rs

94 lines
2.6 KiB
Rust

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<W: Write>(entries: Vec<Entry>, out: &mut W, now: DateTime<Utc>) -> 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).to_string())?;
writeln!(out, "DTSTAMP:{start}", start=entry.start.format(ICAL_TIME_FORMAT).to_string())?;
writeln!(out, "DTSTART:{start}", start=entry.start.format(ICAL_TIME_FORMAT).to_string())?;
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 crate::test_utils::Ps;
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!(Ps(&String::from_utf8_lossy(&out)), Ps(&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)));
}
}