mirror of
https://github.com/lennart-k/rustical.git
synced 2026-01-30 09:18:22 +00:00
implement text-match and prop-filter for carddav
This commit is contained in:
@@ -2,6 +2,7 @@ use crate::{
|
||||
address_object::AddressObjectPropWrapperName,
|
||||
addressbook::methods::report::addressbook_query::PropFilterElement,
|
||||
};
|
||||
use ical::property::Property;
|
||||
use rustical_dav::xml::{PropfindType, TextMatchElement};
|
||||
use rustical_ical::{AddressObject, UtcDateTime};
|
||||
use rustical_xml::XmlDeserialize;
|
||||
@@ -28,6 +29,22 @@ pub struct ParamFilterElement {
|
||||
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)]
|
||||
#[allow(dead_code)]
|
||||
// <!ELEMENT filter (prop-filter*)>
|
||||
|
||||
@@ -35,7 +35,7 @@ pub struct PropFilterElement {
|
||||
impl PropFilterElement {
|
||||
pub fn match_component(&self, comp: &impl PropFilterable) -> bool {
|
||||
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
|
||||
(true, Some(_))
|
||||
// We don't match
|
||||
@@ -45,22 +45,28 @@ impl PropFilterElement {
|
||||
(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,
|
||||
(false, _) => false,
|
||||
(true, true) => panic!("wat"),
|
||||
};
|
||||
|
||||
// TODO: IMPLEMENT
|
||||
// if let Some(text_match) = &self.text_match
|
||||
// && !text_match.match_property(property)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
let text_matches = self
|
||||
.text_match
|
||||
.iter()
|
||||
.map(|text_match| text_match.match_property(property));
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ pub struct TextMatchElement {
|
||||
|
||||
impl TextMatchElement {
|
||||
#[must_use]
|
||||
pub fn match_property(&self, property: &Property) -> bool {
|
||||
pub fn match_text(&self, haystack: &str) -> bool {
|
||||
let Self {
|
||||
collation,
|
||||
negate_condition,
|
||||
@@ -123,14 +123,15 @@ impl TextMatchElement {
|
||||
match_type,
|
||||
} = self;
|
||||
|
||||
let matches = property
|
||||
.value
|
||||
.as_ref()
|
||||
.is_some_and(|haystack| match_type.match_text(collation, needle, haystack));
|
||||
|
||||
let matches = match_type.match_text(collation, needle, haystack);
|
||||
// XOR
|
||||
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)]
|
||||
|
||||
Reference in New Issue
Block a user