Source code for pymap.parsing.specials.flag


from __future__ import annotations

from functools import total_ordering
from typing import Any

from .. import Params, Parseable, Space
from ..exceptions import NotParseable
from ..primitives import Atom

__all__ = ['Flag', 'get_system_flags', 'Seen', 'Recent', 'Deleted', 'Flagged',
           'Answered', 'Draft', 'Wildcard']


[docs] @total_ordering class Flag(Parseable[bytes]): """Represents a message flag from an IMAP stream. Args: value: The flag or keyword value. """ def __init__(self, value: str | bytes) -> None: super().__init__() if isinstance(value, bytes): value_bytes = value else: value_bytes = bytes(value, 'ascii') self._value = self._capitalize(value_bytes) self._hash = hash(self._value) @property def value(self) -> bytes: """The flag or keyword value.""" return self._value @property def is_system(self) -> bool: """True if the flag is an RFC-defined IMAP system flag.""" return self.value.startswith(b'\\') @classmethod def _capitalize(cls, value: bytes) -> bytes: if value.startswith(b'\\'): return b'\\' + value[1:].capitalize() return value def __eq__(self, other: Any) -> bool: if isinstance(other, Flag): return self._value == other._value elif isinstance(other, bytes): return self._value == self._capitalize(other) return super().__eq__(other) def __lt__(self, other: Any) -> bool: if isinstance(other, Flag): other_bytes = bytes(other) elif isinstance(other, bytes): other_bytes = self._capitalize(other) else: return NotImplemented if self.is_system and not other_bytes.startswith(b'\\'): return True elif not self.is_system and other_bytes.startswith(b'\\'): return False return bytes(self) < other_bytes def __hash__(self) -> int: return self._hash def __repr__(self) -> str: return '<{0} value={1!r}>'.format(type(self).__name__, bytes(self)) def __bytes__(self) -> bytes: return self.value def __str__(self) -> str: return self.value.decode('ascii')
[docs] @classmethod def parse(cls, buf: memoryview, params: Params) \ -> tuple[Flag, memoryview]: try: _, buf = Space.parse(buf, params) except NotParseable: pass if buf: if buf[0] == 0x5c: atom, buf = Atom.parse(buf[1:], params) return cls(b'\\' + atom.value), buf else: atom, buf = Atom.parse(buf, params) return cls(atom.value), buf raise NotParseable(buf)
[docs] def get_system_flags() -> frozenset[Flag]: """Return the set of implemented system flags.""" return frozenset({Seen, Recent, Deleted, Flagged, Answered, Draft})
#: The ``\\Seen`` system flag. Seen = Flag(br'\Seen') #: The ``\\Recent`` system flag. Recent = Flag(br'\Recent') #: The ``\\Deleted`` system flag. Deleted = Flag(br'\Deleted') #: The ``\\Flagged`` system flag. Flagged = Flag(br'\Flagged') #: The ``\\Answered`` system flag. Answered = Flag(br'\Answered') #: The ``\\Draft`` system flag. Draft = Flag(br'\Draft') #: The ``\\*`` special wildcard flag. Wildcard = Flag(br'\*')