Coverage for src / ezpl / handlers / wizard / json.py: 89.19%
31 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-13 19:35 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-13 19:35 +0000
1# ///////////////////////////////////////////////////////////////
2# EZPL - Wizard JSON Mixin
3# Project: ezpl
4# ///////////////////////////////////////////////////////////////
6"""
7JSON methods mixin for Rich Wizard.
9This module provides JSON display functionality for the RichWizard class.
10"""
12from __future__ import annotations
14# ///////////////////////////////////////////////////////////////
15# IMPORTS
16# ///////////////////////////////////////////////////////////////
17# Standard library imports
18import json
20# Third-party imports
21from rich.console import Console
22from rich.json import JSON
23from rich.panel import Panel
25# Local imports
26from ...utils import safe_str_convert
28# ///////////////////////////////////////////////////////////////
29# CLASSES
30# ///////////////////////////////////////////////////////////////
33class JsonMixin:
34 """
35 Mixin providing JSON display methods for RichWizard.
37 This mixin adds JSON display functionality with syntax highlighting
38 and optional panel wrapping.
39 """
41 # Type hints for attributes provided by RichWizard
42 _console: Console
44 # ///////////////////////////////////////////////////////////////
45 # JSON METHODS
46 # ///////////////////////////////////////////////////////////////
48 def json(
49 self,
50 data: str | dict | list,
51 title: str | None = None,
52 indent: int | None = None,
53 highlight: bool = True,
54 ) -> None:
55 """
56 Display JSON data in a formatted and syntax-highlighted way using Rich.
58 Args:
59 data: JSON data to display (dict, list, or JSON string)
60 title: Optional title for the JSON display
61 indent: Number of spaces for indentation (default: 2)
62 highlight: Whether to enable syntax highlighting (default: True)
64 Examples:
65 >>> wizard.json({"name": "Alice", "age": 30})
66 >>> wizard.json('{"key": "value"}', title="Config")
67 >>> wizard.json([1, 2, 3], indent=4)
68 """
69 try:
70 # Convert data to JSON string if needed
71 if isinstance(data, str):
72 # Try to parse and re-format for consistency
73 try:
74 parsed = json.loads(data)
75 json_str = json.dumps(parsed, ensure_ascii=False)
76 except json.JSONDecodeError:
77 # If invalid JSON, use as-is
78 json_str = data
79 else:
80 # Convert dict/list to JSON string
81 json_str = json.dumps(data, ensure_ascii=False)
83 # Create Rich JSON object with proper parameters
84 # Note: Rich's JSON class handles indentation internally via its indent parameter
85 rich_json = JSON(json_str, indent=indent or 2, highlight=highlight)
87 # Display with optional title
88 if title:
89 panel = Panel(rich_json, title=title, border_style="blue")
90 self._console.print(panel)
91 else:
92 self._console.print(rich_json)
94 except Exception as e:
95 # Fallback: try to display as string
96 try:
97 fallback_msg = (
98 f"[yellow]JSON Display Error:[/yellow] {type(e).__name__}"
99 )
100 if title: 100 ↛ 101line 100 didn't jump to line 101 because the condition on line 100 was never true
101 self._console.print(
102 Panel(fallback_msg, title=title, border_style="red")
103 )
104 else:
105 self._console.print(fallback_msg)
106 # Also try to print the raw data
107 self._console.print(f"[dim]Raw data:[/dim] {safe_str_convert(data)}")
108 except Exception as e:
109 raise ValueError(f"Failed to display JSON: {e}") from e