use sha2::{Digest, Sha256};
use vparser::Parser;
const ICS_FIELDS_TO_IGNORE: &[&str] = &[
"PRODID",
"DTSTAMP",
"LAST-MODIFIED",
];
pub(crate) fn hash(input: impl AsRef<str>) -> String {
let mut hasher = Sha256::new();
let parser = Parser::new(input.as_ref());
for line in parser {
if ICS_FIELDS_TO_IGNORE.contains(&line.name().as_ref()) {
continue;
}
let raw = line.raw();
if raw.is_empty() {
continue;
}
hasher.update(line.unfolded().as_ref());
hasher.update("\r\n"); }
format!("{:X}", hasher.finalize())
}
pub(crate) fn replace_uid(orig: &str, new_uid: &str) -> String {
let mut inside_component = false;
let mut new = String::new();
for line in Parser::new(orig) {
if line.name() == "BEGIN"
&& ["VEVENT", "VTODO", "VJOURNAL", "VCARD"].contains(&line.value().as_ref())
{
inside_component = true;
}
if line.name() == "END"
&& ["VEVENT", "VTODO", "VJOURNAL", "VCARD"].contains(&line.value().as_ref())
{
inside_component = false;
}
if inside_component && line.name() == "UID" {
new.push_str("UID:");
new.push_str(new_uid);
new.push_str("\r\n");
} else {
new.push_str(line.raw());
new.push_str("\r\n");
}
}
new
}
#[cfg(test)]
mod test {
use crate::util::hash;
#[test]
fn compare_hashing_with_and_without_prodid() {
let without_prodid = [
"BEGIN:VCALENDAR",
"BEGIN:VEVENT",
"DTSTART:19970714T170000Z",
"DTEND:19970715T035959Z",
"SUMMARY:Bastille Day Party",
"UID:11bb6bed-c29b-4999-a627-12dee35f8395",
"END:VEVENT",
"END:VCALENDAR",
]
.join("\r\n");
let with_prodid = [
"PRODID:test-client",
"BEGIN:VCALENDAR",
"BEGIN:VEVENT",
"DTSTART:19970714T170000Z",
"DTEND:19970715T035959Z",
"SUMMARY:Bastille Day Party",
"UID:11bb6bed-c29b-4999-a627-12dee35f8395",
"END:VEVENT",
"END:VCALENDAR",
]
.join("\r\n");
assert_eq!(hash(without_prodid), hash(with_prodid));
}
#[test]
fn compare_hashing_with_different_folding() {
let first = [
"DESCRIPTION:Voor meer informatie zie https://nluug.nl/evenementen/nluug/na",
" jaarsconferentie-2023/",
]
.join("\r\n");
let second = [
"DESCRIPTION:Voor meer informatie zie https:",
" //nluug.nl/evenementen/nluug/najaarsconferentie-2023/",
]
.join("\r\n");
assert_eq!(hash(first), hash(second));
}
}