aboutsummaryrefslogtreecommitdiff
path: root/ctec/imap_response.py
diff options
context:
space:
mode:
Diffstat (limited to 'ctec/imap_response.py')
-rw-r--r--ctec/imap_response.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/ctec/imap_response.py b/ctec/imap_response.py
new file mode 100644
index 0000000..23ca943
--- /dev/null
+++ b/ctec/imap_response.py
@@ -0,0 +1,46 @@
+# this should really be in the stdlib imo
+from dataclasses import dataclass
+from typing import List as ListT, Union, ClassVar
+
+from .parse_utils import ParseResult, Parser, take_while1, tag, delimited, take_n, alt, map_parser, separated_many0, separated_triple, all_consuming
+
+__all__ = [
+ 'List',
+]
+
+atom: Parser[str] = take_while1(lambda c: c.isalnum() or c in r'\/')
+
+number: Parser[int] = map_parser(take_while1(str.isnumeric), int)
+
+def literal_string(text: str) -> ParseResult[str]:
+ delimited_result = delimited(tag('{'), number, tag('}\r\n'))(text)
+ if delimited_result is None:
+ return None
+ count, text = delimited_result
+ return take_n(count)(text)
+
+quoted_string: Parser[str] = delimited(tag('"'), take_while1(lambda c: c not in '\r\n"'), tag('"'))
+
+string: Parser[str] = alt(literal_string, quoted_string)
+
+astring: Parser[str] = alt(atom, string)
+
+data_item: Parser[Union[int, str]] = alt(number, atom, string)
+
+ParensList = ListT[Union[int, str, 'ParensList']]
+def parens_list(text: str) -> ParseResult[ParensList]:
+ return delimited(tag('('), separated_many0(alt(data_item, parens_list), tag(' ')), tag(')'))(text)
+
+@dataclass
+class List:
+ attributes: ListT[str]
+ delimiter: str
+ name: str
+
+ @staticmethod
+ def parse(response: bytes) -> 'List':
+ response = response.decode('ASCII')
+ print(response)
+ parser = all_consuming(separated_triple(parens_list, tag(' '), string, tag(' '), astring), debug=True)
+ (attributes, delimiter, name), _ = parser(response)
+ return List(attributes, delimiter, name)