Implement integer parsing
authorDavid Kerkeslager <kerkeslager@gmail.com>
Thu, 13 Apr 2017 17:09:15 +0000 (13:09 -0400)
committerDavid Kerkeslager <kerkeslager@gmail.com>
Thu, 13 Apr 2017 17:09:15 +0000 (13:09 -0400)
don/string.py
test_don.py

index 15ffc10..c7d810b 100644 (file)
@@ -1,4 +1,5 @@
 import binascii
 import binascii
+import re
 
 from don import tags, _shared
 
 
 from don import tags, _shared
 
@@ -72,10 +73,31 @@ def _make_constant_parser(constant, value):
 
     return parser
 
 
     return parser
 
+def _make_integer_parser(width):
+    matcher = re.compile(r'(-?\d+)i' + str(width))
+
+    def parser(s):
+        match = matcher.match(s)
+
+        if match:
+            return _shared.ParseResult(
+                success = True,
+                value = int(match.group(1)),
+                remaining = s[match.end():],
+            )
+
+        return _shared._FAILED_PARSE_RESULT
+
+    return parser
+
 _PARSERS = [
     _make_constant_parser('null', None),
     _make_constant_parser('true', True),
     _make_constant_parser('false', False),
 _PARSERS = [
     _make_constant_parser('null', None),
     _make_constant_parser('true', True),
     _make_constant_parser('false', False),
+    _make_integer_parser(8),
+    _make_integer_parser(16),
+    _make_integer_parser(32),
+    _make_integer_parser(64),
 ]
 
 def _object_parser(source):
 ]
 
 def _object_parser(source):
@@ -90,10 +112,13 @@ def _object_parser(source):
 def _parse(parser, source):
     result = parser(source)
 
 def _parse(parser, source):
     result = parser(source)
 
-    if result.success and result.remaining.strip() == '':
-        return result.value
+    if result.success:
+        if result.remaining.strip() == '':
+            return result.value
+
+        raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining))
 
 
-    raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining))
+    raise Exception('Unable to parse: "{}"'.format(source))
 
 def deserialize(s):
     return _parse(_object_parser, s)
 
 def deserialize(s):
     return _parse(_object_parser, s)
index df91309..46034ec 100644 (file)
@@ -192,4 +192,20 @@ class TestStringDeserialize(unittest.TestCase):
             string.deserialize('false'),
         )
 
             string.deserialize('false'),
         )
 
+    def test_deserializes_int8(self):
+        self.assertEqual(10, string.deserialize('10i8'))
+        self.assertEqual(-1, string.deserialize('-1i8'))
+
+    def test_deserializes_int16(self):
+        self.assertEqual(10, string.deserialize('10i16'))
+        self.assertEqual(-1, string.deserialize('-1i16'))
+
+    def test_deserializes_int32(self):
+        self.assertEqual(10, string.deserialize('10i32'))
+        self.assertEqual(-1, string.deserialize('-1i32'))
+
+    def test_deserializes_int64(self):
+        self.assertEqual(10, string.deserialize('10i64'))
+        self.assertEqual(-1, string.deserialize('-1i64'))
+
 unittest.main()
 unittest.main()