diff --git a/configforge/formatters/json_handler.py b/configforge/formatters/json_handler.py new file mode 100644 index 0000000..c271c91 --- /dev/null +++ b/configforge/formatters/json_handler.py @@ -0,0 +1,52 @@ +"""JSON format handler for ConfigForge.""" + +import json +from typing import Any, Dict + +from configforge.exceptions import ConversionError + + +class JSONHandler: + """Handler for JSON configuration files.""" + + @staticmethod + def loads(content: str) -> Dict[str, Any]: + """Parse JSON content.""" + try: + return json.loads(content) + except json.JSONDecodeError as e: + raise ConversionError(f"Invalid JSON: {str(e)}") from e + + @staticmethod + def dumps(data: Any, indent: int = 2) -> str: + """Serialize data to JSON string.""" + try: + return json.dumps(data, indent=indent, ensure_ascii=False) + except (TypeError, ValueError) as e: + raise ConversionError(f"Failed to serialize JSON: {str(e)}") from e + + @staticmethod + def read(filepath: str) -> Dict[str, Any]: + """Read and parse JSON file.""" + try: + with open(filepath, "r", encoding="utf-8") as f: + return json.load(f) + except FileNotFoundError: + raise ConversionError(f"File not found: {filepath}") + except PermissionError: + raise ConversionError(f"Permission denied: {filepath}") + except json.JSONDecodeError as e: + raise ConversionError(f"Invalid JSON in {filepath}: {str(e)}") from e + + @staticmethod + def write(filepath: str, data: Any, indent: int = 2) -> None: + """Write data to JSON file.""" + try: + with open(filepath, "w", encoding="utf-8") as f: + json.dump(data, f, indent=indent, ensure_ascii=False) + except FileNotFoundError: + raise ConversionError(f"Directory not found for: {filepath}") + except PermissionError: + raise ConversionError(f"Permission denied to write: {filepath}") + except (TypeError, ValueError) as e: + raise ConversionError(f"Failed to write JSON: {str(e)}") from e