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

1# /////////////////////////////////////////////////////////////// 

2# EZPL - Wizard JSON Mixin 

3# Project: ezpl 

4# /////////////////////////////////////////////////////////////// 

5 

6""" 

7JSON methods mixin for Rich Wizard. 

8 

9This module provides JSON display functionality for the RichWizard class. 

10""" 

11 

12from __future__ import annotations 

13 

14# /////////////////////////////////////////////////////////////// 

15# IMPORTS 

16# /////////////////////////////////////////////////////////////// 

17# Standard library imports 

18import json 

19 

20# Third-party imports 

21from rich.console import Console 

22from rich.json import JSON 

23from rich.panel import Panel 

24 

25# Local imports 

26from ...utils import safe_str_convert 

27 

28# /////////////////////////////////////////////////////////////// 

29# CLASSES 

30# /////////////////////////////////////////////////////////////// 

31 

32 

33class JsonMixin: 

34 """ 

35 Mixin providing JSON display methods for RichWizard. 

36 

37 This mixin adds JSON display functionality with syntax highlighting 

38 and optional panel wrapping. 

39 """ 

40 

41 # Type hints for attributes provided by RichWizard 

42 _console: Console 

43 

44 # /////////////////////////////////////////////////////////////// 

45 # JSON METHODS 

46 # /////////////////////////////////////////////////////////////// 

47 

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. 

57 

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) 

63 

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) 

82 

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) 

86 

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) 

93 

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