implement text-match and prop-filter for carddav

This commit is contained in:
Lennart
2025-12-31 13:02:53 +01:00
parent bfcd94f096
commit 47c2a55941
3 changed files with 40 additions and 16 deletions

View File

@@ -2,6 +2,7 @@ use crate::{
address_object::AddressObjectPropWrapperName, address_object::AddressObjectPropWrapperName,
addressbook::methods::report::addressbook_query::PropFilterElement, addressbook::methods::report::addressbook_query::PropFilterElement,
}; };
use ical::property::Property;
use rustical_dav::xml::{PropfindType, TextMatchElement}; use rustical_dav::xml::{PropfindType, TextMatchElement};
use rustical_ical::{AddressObject, UtcDateTime}; use rustical_ical::{AddressObject, UtcDateTime};
use rustical_xml::XmlDeserialize; use rustical_xml::XmlDeserialize;
@@ -28,6 +29,22 @@ pub struct ParamFilterElement {
pub(crate) name: String, pub(crate) name: String,
} }
impl ParamFilterElement {
pub fn match_property(&self, prop: &Property) -> bool {
let Some(param) = prop.get_param(&self.name) else {
return self.is_not_defined.is_some();
};
if self.is_not_defined.is_some() {
return false;
}
let Some(text_match) = self.text_match.as_ref() else {
return true;
};
text_match.match_text(param)
}
}
#[derive(XmlDeserialize, Clone, Debug, PartialEq, Eq)] #[derive(XmlDeserialize, Clone, Debug, PartialEq, Eq)]
#[allow(dead_code)] #[allow(dead_code)]
// <!ELEMENT filter (prop-filter*)> // <!ELEMENT filter (prop-filter*)>

View File

@@ -35,7 +35,7 @@ pub struct PropFilterElement {
impl PropFilterElement { impl PropFilterElement {
pub fn match_component(&self, comp: &impl PropFilterable) -> bool { pub fn match_component(&self, comp: &impl PropFilterable) -> bool {
let property = comp.get_property(&self.name); let property = comp.get_property(&self.name);
let _property = match (self.is_not_defined.is_some(), property) { let property = match (self.is_not_defined.is_some(), property) {
// We are the component that's not supposed to be defined // We are the component that's not supposed to be defined
(true, Some(_)) (true, Some(_))
// We don't match // We don't match
@@ -45,22 +45,28 @@ impl PropFilterElement {
(false, Some(property)) => property (false, Some(property)) => property
}; };
let _allof = match (self.allof.is_some(), self.anyof.is_some()) { let allof = match (self.allof.is_some(), self.anyof.is_some()) {
(true, false) => true, (true, false) => true,
(false, _) => false, (false, _) => false,
(true, true) => panic!("wat"), (true, true) => panic!("wat"),
}; };
// TODO: IMPLEMENT let text_matches = self
// if let Some(text_match) = &self.text_match .text_match
// && !text_match.match_property(property) .iter()
// { .map(|text_match| text_match.match_property(property));
// return false;
// }
// TODO: param-filter let param_matches = self
.param_filter
.iter()
.map(|param_filter| param_filter.match_property(property));
let mut matches = text_matches.chain(param_matches);
true if allof {
matches.all(|a| a)
} else {
matches.any(|a| a)
}
} }
} }

View File

@@ -115,7 +115,7 @@ pub struct TextMatchElement {
impl TextMatchElement { impl TextMatchElement {
#[must_use] #[must_use]
pub fn match_property(&self, property: &Property) -> bool { pub fn match_text(&self, haystack: &str) -> bool {
let Self { let Self {
collation, collation,
negate_condition, negate_condition,
@@ -123,14 +123,15 @@ impl TextMatchElement {
match_type, match_type,
} = self; } = self;
let matches = property let matches = match_type.match_text(collation, needle, haystack);
.value
.as_ref()
.is_some_and(|haystack| match_type.match_text(collation, needle, haystack));
// XOR // XOR
negate_condition.0 ^ matches negate_condition.0 ^ matches
} }
#[must_use]
pub fn match_property(&self, property: &Property) -> bool {
let text = property.value.as_deref().unwrap_or("");
self.match_text(text)
}
} }
#[cfg(test)] #[cfg(test)]