diff --git a/carddav/carddav.go b/carddav/carddav.go index ae04f61..fbc9e3b 100644 --- a/carddav/carddav.go +++ b/carddav/carddav.go @@ -20,9 +20,52 @@ type AddressBookQuery struct { Props []string AllProp bool + PropFilters []PropFilter + FilterTest FilterTest // defaults to FilterAnyOf + Limit int // <= 0 means unlimited } +type PropFilter struct { + Name string + + // if IsNotDefined is set, TextMatches and Params need to be unset + IsNotDefined bool + TextMatches []TextMatch + Params []ParamFilter +} + +type ParamFilter struct { + Name string + Test FilterTest // defaults to FilterAnyOf + + // if IsNotDefined is set, TextMatch needs to be unset + IsNotDefined bool + TextMatch *TextMatch +} + +type TextMatch struct { + Text string + NegateCondition bool + MatchType MatchType // defaults to MatchContains +} + +type FilterTest string + +const ( + FilterAnyOf FilterTest = "anyof" + FilterAllOf FilterTest = "allof" +) + +type MatchType string + +const ( + MatchEquals MatchType = "equals" + MatchContains MatchType = "contains" + MatchStartsWith MatchType = "starts-with" + MatchEndsWith MatchType = "ends-with" +) + type AddressBookMultiGet struct { Paths []string diff --git a/carddav/elements.go b/carddav/elements.go index effcfab..49f3e3a 100644 --- a/carddav/elements.go +++ b/carddav/elements.go @@ -71,19 +71,13 @@ type filter struct { type filterTest string -const ( - filterAnyOf filterTest = "anyof" - filterAllOf filterTest = "allof" -) - func (ft *filterTest) UnmarshalText(b []byte) error { - v := filterTest(b) - switch v { - case filterAnyOf, filterAllOf: - *ft = v + switch FilterTest(b) { + case FilterAnyOf, FilterAllOf: + *ft = filterTest(b) return nil default: - return fmt.Errorf("carddav: invalid filter test value: %q", v) + return fmt.Errorf("carddav: invalid filter test value: %q", string(b)) } } @@ -94,8 +88,8 @@ type propFilter struct { Test filterTest `xml:"test,attr,omitempty"` IsNotDefined *struct{} `xml:"is-not-defined,omitempty"` - TextMatch []textMatch `xml:"text-match"` - ParamFilter []paramFilter `xml:"param-filter"` + TextMatch []textMatch `xml:"text-match,omitempty"` + ParamFilter []paramFilter `xml:"param-filter,omitempty"` } // https://tools.ietf.org/html/rfc6352#section-10.5.4 @@ -128,23 +122,15 @@ func (nc negateCondition) MarshalText() ([]byte, error) { return nil, nil } -type matchType string - -const ( - matchEquals matchType = "equals" - matchContains matchType = "contains" - matchStartsWith matchType = "starts-with" - matchEndsWith matchType = "ends-with" -) +type matchType MatchType func (mt *matchType) UnmarshalText(b []byte) error { - v := matchType(b) - switch v { - case matchEquals, matchContains, matchStartsWith, matchEndsWith: - *mt = v + switch MatchType(b) { + case MatchEquals, MatchContains, MatchStartsWith, MatchEndsWith: + *mt = matchType(b) return nil default: - return fmt.Errorf("carddav: invalid match type value: %q", v) + return fmt.Errorf("carddav: invalid match type value: %q", string(b)) } }