Additional accept functionality

This commit is contained in:
Adam Hopkins 2023-01-25 00:13:44 +02:00
parent 4ad8168bb0
commit 43c9a0a49b
No known key found for this signature in database
GPG Key ID: 9F85EE6C807303FB

View File

@ -105,27 +105,27 @@ class Accept(str):
return NotImplemented return NotImplemented
@parse_arg_as_accept @parse_arg_as_accept
def __lt__(self, other: Union[str, Accept]): def __lt__(self, other: AcceptLike):
return self._compare(other, lambda s, o: s < o) return self._compare(other, lambda s, o: s < o)
@parse_arg_as_accept @parse_arg_as_accept
def __le__(self, other: Union[str, Accept]): def __le__(self, other: AcceptLike):
return self._compare(other, lambda s, o: s <= o) return self._compare(other, lambda s, o: s <= o)
@parse_arg_as_accept @parse_arg_as_accept
def __eq__(self, other: Union[str, Accept]): # type: ignore def __eq__(self, other: AcceptLike): # type: ignore
return self._compare(other, lambda s, o: s == o) return self._compare(other, lambda s, o: s == o)
@parse_arg_as_accept @parse_arg_as_accept
def __ge__(self, other: Union[str, Accept]): def __ge__(self, other: AcceptLike):
return self._compare(other, lambda s, o: s >= o) return self._compare(other, lambda s, o: s >= o)
@parse_arg_as_accept @parse_arg_as_accept
def __gt__(self, other: Union[str, Accept]): def __gt__(self, other: AcceptLike):
return self._compare(other, lambda s, o: s > o) return self._compare(other, lambda s, o: s > o)
@parse_arg_as_accept @parse_arg_as_accept
def __ne__(self, other: Union[str, Accept]): # type: ignore def __ne__(self, other: AcceptLike): # type: ignore
return self._compare(other, lambda s, o: s != o) return self._compare(other, lambda s, o: s != o)
@parse_arg_as_accept @parse_arg_as_accept
@ -157,8 +157,16 @@ class Accept(str):
return type_match and subtype_match return type_match and subtype_match
@property
def has_wildcard(self) -> bool:
return self.type_.is_wildcard or self.subtype.is_wildcard
@property
def is_wildcard(self) -> bool:
return self.type_.is_wildcard and self.subtype.is_wildcard
@classmethod @classmethod
def parse(cls, raw: str) -> Accept: def parse(cls, raw: AcceptLike) -> Accept:
invalid = False invalid = False
mtype = raw.strip() mtype = raw.strip()
@ -181,13 +189,16 @@ class Accept(str):
return cls(mtype, MediaType(type_), MediaType(subtype), **params) return cls(mtype, MediaType(type_), MediaType(subtype), **params)
AcceptLike = Union[str, Accept]
class AcceptContainer(list): class AcceptContainer(list):
def __contains__(self, o: object) -> bool: def __contains__(self, o: object) -> bool:
return any(item.match(o) for item in self) return any(item.match(o) for item in self)
def match( def match(
self, self,
o: object, o: AcceptLike,
*, *,
allow_type_wildcard: bool = True, allow_type_wildcard: bool = True,
allow_subtype_wildcard: bool = True, allow_subtype_wildcard: bool = True,
@ -201,6 +212,26 @@ class AcceptContainer(list):
for item in self for item in self
) )
def find_first(
self,
others: List[AcceptLike],
default: AcceptLike = "*/*",
) -> Accept:
filtered = [
accept
for accept in self
if any(accept.match(other) for other in others)
]
if filtered:
return filtered[0]
return Accept.parse(default)
@parse_arg_as_accept
def match_explicit(self, other: AcceptLike) -> bool:
return self.match(
other, allow_type_wildcard=False, allow_subtype_wildcard=False
)
def parse_content_header(value: str) -> Tuple[str, Options]: def parse_content_header(value: str) -> Tuple[str, Options]:
"""Parse content-type and content-disposition header values. """Parse content-type and content-disposition header values.