kerf-engine/engine/output/json_output.py
jlightner 9540f37f70 test: Wire post-processing into /engine/trace, add output_format routin…
- "engine/api/routes.py"
- "engine/tests/test_api.py"

GSD-Task: S02/T03
2026-03-26 04:39:52 +00:00

76 lines
2.1 KiB
Python

"""JSON output generator — structured path data from PostProcessResult."""
from __future__ import annotations
import json
from pipeline.postprocess import PathInfo, PostProcessResult
def _path_to_dict(path: PathInfo) -> dict:
"""Convert a PathInfo to a JSON-serializable dict with path commands."""
commands = []
coords = path.simplified_coords
if not coords:
return {"commands": [], "properties": {}}
# Move to start
commands.append({"type": "M", "x": coords[0][0], "y": coords[0][1]})
# Line to each subsequent point
for x, y in coords[1:]:
commands.append({"type": "L", "x": x, "y": y})
# Close if applicable
if path.is_closed:
commands.append({"type": "Z"})
properties = {
"is_closed": path.is_closed,
"is_island": path.is_island,
"node_count": path.node_count,
"original_node_count": path.original_node_count,
"area": round(path.area, 4),
}
return {"commands": commands, "properties": properties}
def generate_json(result: PostProcessResult) -> str:
"""Generate a JSON string from post-processed path data.
Output format:
{
"paths": [
{
"commands": [{"type": "M", "x": 0, "y": 0}, {"type": "L", "x": 10, "y": 0}, ...],
"properties": {"is_closed": true, "is_island": false, ...}
},
...
],
"metadata": {
"path_count": 2,
"total_nodes": 10,
"total_original_nodes": 50,
"open_path_count": 0,
"island_count": 1
}
}
Args:
result: PostProcessResult from the post-processing pipeline.
Returns:
JSON string.
"""
output = {
"paths": [_path_to_dict(p) for p in result.paths],
"metadata": {
"path_count": len(result.paths),
"total_nodes": result.total_nodes,
"total_original_nodes": result.total_original_nodes,
"open_path_count": result.open_path_count,
"island_count": result.island_count,
},
}
return json.dumps(output, indent=2)