CalDAV calendar-query and free-busy-query REPORT

This commit is contained in:
mdecimus
2025-05-05 12:56:34 +02:00
parent cb03036998
commit 6e89af9698
14 changed files with 1445 additions and 245 deletions

View File

@@ -10,6 +10,7 @@ calcard = { path = "/Users/me/code/calcard", features = ["rkyv"] }
mail-parser = "0.10.2"
hyper = "1.6.0"
rkyv = { version = "0.8.10", features = ["little_endian"] }
chrono = { version = "0.4.40", features = ["serde"], optional = true }
[dev-dependencies]
calcard = { path = "/Users/me/code/calcard", features = ["serde", "rkyv"] }
@@ -18,5 +19,5 @@ serde_json = "1.0.138"
chrono = { version = "0.4.40", features = ["serde"] }
[features]
test_mode = []
test_mode = ["chrono"]
enterprise = []

View File

@@ -383,13 +383,20 @@ impl Tokenizer<'_> {
impl TimeRange {
pub fn is_in_range(&self, match_overlap: bool, start: i64, end: i64) -> bool {
/*let c = println!(
"is_in_range ({match_overlap}): {} to {}, resource from {} to {}, result: {}",
chrono::DateTime::from_timestamp(self.start, 0).unwrap(),
chrono::DateTime::from_timestamp(self.end, 0).unwrap(),
chrono::DateTime::from_timestamp(start, 0).unwrap(),
chrono::DateTime::from_timestamp(end, 0).unwrap(),
result
);*/
if !match_overlap {
// RFC4791#9.9: (start < DTEND AND end > DTSTART)
self.start < end && self.end > start
} else {
// RFC4791#9.9: ((start < DUE) OR (start <= DTSTART)) AND ((end > DTSTART) OR (end >= DUE))
let range = self.start..=self.end;
range.contains(&start) || range.contains(&end)
((start < self.end) || (start <= self.start)) && (end > self.start || end >= self.end)
}
}

View File

@@ -1454,11 +1454,27 @@ impl YesNo {
impl TextMatch {
pub fn matches(&self, text: &str) -> bool {
(match self.match_type {
MatchType::Equals => text == self.value,
MatchType::Contains => text.contains(&self.value),
MatchType::StartsWith => text.starts_with(&self.value),
MatchType::EndsWith => text.ends_with(&self.value),
}) ^ self.negate
match self.collation {
Collation::Octet => {
(match self.match_type {
MatchType::Equals => text == self.value,
MatchType::Contains => text.contains(&self.value),
MatchType::StartsWith => text.starts_with(&self.value),
MatchType::EndsWith => text.ends_with(&self.value),
}) ^ self.negate
}
_ => {
(match self.match_type {
MatchType::Equals => text.to_lowercase() == self.value.to_lowercase(),
MatchType::Contains => text.to_lowercase().contains(&self.value.to_lowercase()),
MatchType::StartsWith => {
text.to_lowercase().starts_with(&self.value.to_lowercase())
}
MatchType::EndsWith => {
text.to_lowercase().ends_with(&self.value.to_lowercase())
}
}) ^ self.negate
}
}
}
}