3 from don import tags, _shared
5 def _integer_size_to_string_serializer(integer_size):
6 minimum = -(2 ** (integer_size - 1))
7 maximum = 2 ** (integer_size - 1) - 1
9 def serializer(integer):
10 assert minimum <= integer and integer <= maximum
11 return '{}i{}'.format(integer, integer_size)
15 def _serialize_float(f):
16 return '{}f'.format(f)
18 def _serialize_double(d):
19 return '{}d'.format(d)
21 def _serialize_binary(b):
22 return '"{}"b'.format(binascii.hexlify(b).decode('ascii'))
24 def _utf_encoding_to_serializer(utf_encoding):
26 return '"{}"{}'.format(s, utf_encoding)
30 def _string_serialize_list(l):
31 return '[{}]'.format(', '.join(map(serialize, l)))
33 def _string_serialize_dictionary(d):
34 def serialize_kvp(kvp):
35 return serialize(kvp[0]) + ': ' + serialize(kvp[1])
36 return '{ ' + ', '.join(map(serialize_kvp, d.items())) + ' }'
38 _STRING_SERIALIZERS = {
39 tags.VOID: lambda o: 'null',
40 tags.TRUE: lambda o: 'true',
41 tags.FALSE: lambda o: 'false',
42 tags.INT8: _integer_size_to_string_serializer(8),
43 tags.INT16: _integer_size_to_string_serializer(16),
44 tags.INT32: _integer_size_to_string_serializer(32),
45 tags.INT64: _integer_size_to_string_serializer(64),
46 tags.FLOAT: _serialize_float,
47 tags.DOUBLE: _serialize_double,
48 tags.BINARY: _serialize_binary,
49 tags.UTF8: _utf_encoding_to_serializer('utf8'),
50 tags.UTF16: _utf_encoding_to_serializer('utf16'),
51 tags.UTF32: _utf_encoding_to_serializer('utf32'),
52 tags.LIST: _string_serialize_list,
53 tags.DICTIONARY: _string_serialize_dictionary,
59 return _STRING_SERIALIZERS[o.tag](o.value)
61 def _make_constant_parser(constant, value):
63 if s.startswith(constant):
64 result = _shared.ParseResult(
67 remaining = s[len(constant):],
71 return _shared._FAILED_PARSE_RESULT
76 _make_constant_parser('null', None),
77 _make_constant_parser('true', True),
78 _make_constant_parser('false', False),
81 def _object_parser(source):
82 for parser in _PARSERS:
83 result = parser(source)
88 return _shared._FAILED_PARSE_RESULT
90 def _parse(parser, source):
91 result = parser(source)
93 if result.success and result.remaining.strip() == '':
96 raise Exception('Unparsed trailing characters: "{}"'.format(result.remaining))
99 return _parse(_object_parser, s)