Source code for pudding.writer.writers.json

"""Module defining json writer class."""

import json

from .writer import BufferedWriter
from ..node import Node

type JsonType = dict[str, JsonType | list[JsonType] | str]


def _to_json(node: Node) -> JsonType:
    """Create a json type objects from node.

    :param node: Node object to convert.
    :returns: The JsonType object.
    """
    elem: JsonType = {}
    for k, v in node.attribs.items():
        elem[f"@{k}"] = v
    if node.text is not None:
        elem["#text"] = node.text
    for child in node.get_sorted_children():
        existing = elem.get(child.name)
        if isinstance(existing, str):
            raise RuntimeError
        if not existing:
            elem[child.name] = _to_json(child)
            continue
        if not isinstance(existing, list):
            existing = [existing]
        existing.append(_to_json(child))
        elem[child.name] = existing
    return elem


[docs] class Json(BufferedWriter): """Writer class for json output."""
[docs] def serialize_node(self, node: Node, parent: JsonType) -> JsonType: """Convert node object to json.""" existing = parent.get(node.name) if isinstance(existing, str): raise RuntimeError if not existing: parent[node.name] = _to_json(node) return parent if not isinstance(existing, list): existing = [existing] existing.append(_to_json(node)) parent[node.name] = existing return parent
[docs] def generate_output(self) -> str: """Generate output in specified format.""" base: JsonType = {} for child in self.root.get_sorted_children(): base = self.serialize_node(child, base) return json.dumps(base, indent=4)