mirror of
https://github.com/lennart-k/rustical.git
synced 2026-01-30 11:48:18 +00:00
implement text-match and prop-filter for carddav
This commit is contained in:
@@ -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*)>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
Reference in New Issue
Block a user