Source code for robot.htmldata.jsonwriter

#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  See the License for the specific language governing permissions and
#  limitations under the License.

from robot.utils import PY2

[docs]class JsonWriter(object): def __init__(self, output, separator=''): self._writer = JsonDumper(output) self._separator = separator
[docs] def write_json(self, prefix, data, postfix=';\n', mapping=None, separator=True): self._writer.write(prefix) self._writer.dump(data, mapping) self._writer.write(postfix) self._write_separator(separator)
[docs] def write(self, string, postfix=';\n', separator=True): self._writer.write(string + postfix) self._write_separator(separator)
def _write_separator(self, separator): if separator and self._separator: self._writer.write(self._separator)
[docs]class JsonDumper(object): def __init__(self, output): self._output = output self._dumpers = (MappingDumper(self), IntegerDumper(self), TupleListDumper(self), StringDumper(self), NoneDumper(self), DictDumper(self))
[docs] def dump(self, data, mapping=None): for dumper in self._dumpers: if dumper.handles(data, mapping): dumper.dump(data, mapping) return raise ValueError('Dumping %s not supported.' % type(data))
[docs] def write(self, data): self._output.write(data)
class _Dumper(object): _handled_types = None def __init__(self, jsondumper): self._dump = jsondumper.dump self._write = jsondumper.write def handles(self, data, mapping): return isinstance(data, self._handled_types) def dump(self, data, mapping): raise NotImplementedError
[docs]class StringDumper(_Dumper): _handled_types = (str, unicode) if PY2 else str _search_and_replace = [('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'), ('\n', '\\n'), ('\r', '\\r'), ('</', '\\x3c/')]
[docs] def dump(self, data, mapping): self._write('"%s"' % (self._escape(data) if data else ''))
def _escape(self, string): for search, replace in self._search_and_replace: if search in string: string = string.replace(search, replace) return string
[docs]class IntegerDumper(_Dumper): # Handles also bool _handled_types = (int, long) if PY2 else int
[docs] def dump(self, data, mapping): self._write(str(data).lower())
[docs]class DictDumper(_Dumper): _handled_types = dict
[docs] def dump(self, data, mapping): self._write('{') last_index = len(data) - 1 for index, key in enumerate(sorted(data)): self._dump(key, mapping) self._write(':') self._dump(data[key], mapping) if index < last_index: self._write(',') self._write('}')
[docs]class TupleListDumper(_Dumper): _handled_types = (tuple, list)
[docs] def dump(self, data, mapping): self._write('[') last_index = len(data) - 1 for index, item in enumerate(data): self._dump(item, mapping) if index < last_index: self._write(',') self._write(']')
[docs]class MappingDumper(_Dumper):
[docs] def handles(self, data, mapping): try: return mapping and data in mapping except TypeError: return False
[docs] def dump(self, data, mapping): self._write(mapping[data])
[docs]class NoneDumper(_Dumper):
[docs] def handles(self, data, mapping): return data is None
[docs] def dump(self, data, mapping): self._write('null')