use ical::{component::vevent::VEVENT, prop::description::DESCRIPTION, tree::cst::IcalCst};
fn main() {
let messy = concat!(
"BEGIN:VCALENDAR\r\n",
"VERSION:2.0\r\n",
"PRODID:-//Example//EN\n",
"BEGIN:VEVENT\r\n",
"UID:messy@example.com\r\n",
"\r\n",
"DTSTAMP:20260101T000000Z\r\n",
"DESCRIPTION;ENCODING=QUOTED-PRINTABLE:caf=\r\n",
"=C3=A9 at the corner\r\n",
"SUMMARY:A calendar written by a real exporter, folded acro\r\n",
" ss two physical lines\r\n",
"END:VEVENT\r\n",
"END:VCALENDAR\r\n",
);
let mut cst = IcalCst::parse(messy).expect("liberal in");
assert_eq!(cst.to_string(), messy);
println!("round-tripped byte for byte: {}", cst.to_string() == messy);
let event = cst.component_mut::<VEVENT>().expect("the event");
let value = event.prop_mut::<DESCRIPTION>().expect("the description");
println!("the soft-broken value reads: {:?}", value.text());
let broken = concat!(
"BEGIN:VCALENDAR\r\n",
"VERSION:2.0\r\n",
"PRODID:-//Example//EN\r\n",
"THIS LINE HAS NO COLON\r\n",
"BEGIN:VEVENT\r\n",
"UID:unterminated@example.com\r\n",
"END:VCALENDAR\r\n",
);
println!("\nstrict parse: {:?}", IcalCst::parse(broken).is_err());
let recovery = IcalCst::parse_recovering(broken);
println!(
"recovered {} calendar(s), working around:",
recovery.calendars.len()
);
for problem in &recovery.problems {
println!(" {problem}");
}
let out: String = recovery.calendars.iter().map(IcalCst::to_string).collect();
println!("\nand still round-trips: {}", out == broken);
}