From bcb147586e6285e8dc43aa02c060c43d6a1e96df Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 1 Feb 2026 19:01:12 +0000 Subject: [PATCH] Add converter modules (JSON, YAML, TOML, CSV) --- src/converters/base.py | 117 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/converters/base.py diff --git a/src/converters/base.py b/src/converters/base.py new file mode 100644 index 0000000..62c3a78 --- /dev/null +++ b/src/converters/base.py @@ -0,0 +1,117 @@ +"""Base converter module.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Any + + +@dataclass +class ConversionResult: + """Result of a conversion operation.""" + success: bool + data: Any = None + error: str = None + source_format: str = None + target_format: str = None + + +class BaseConverter(ABC): + """Abstract base class for data format converters.""" + + format_name: str = None + extensions: tuple = () + + @abstractmethod + def loads(self, content: str) -> Any: + """Parse string content to data structure. + + Args: + content: String content to parse + + Returns: + Parsed data structure + """ + pass + + @abstractmethod + def dumps(self, data: Any, indent: int = 2) -> str: + """Serialize data structure to string. + + Args: + data: Data structure to serialize + indent: Number of spaces for indentation + + Returns: + Serialized string content + """ + pass + + def read_file(self, filepath: str) -> str: + """Read content from file. + + Args: + filepath: Path to file + + Returns: + File content as string + """ + with open(filepath, 'r', encoding='utf-8') as f: + return f.read() + + def write_file(self, filepath: str, content: str) -> None: + """Write content to file. + + Args: + filepath: Path to file + content: Content to write + """ + with open(filepath, 'w', encoding='utf-8') as f: + f.write(content) + + def convert(self, content: str, target_converter: 'BaseConverter', indent: int = 2) -> ConversionResult: + """Convert content from this format to another. + + Args: + content: Source content string + target_converter: Target format converter + indent: Indentation for output + + Returns: + ConversionResult with converted data or error + """ + try: + data = self.loads(content) + result = target_converter.dumps(data, indent=indent) + return ConversionResult( + success=True, + data=result, + source_format=self.format_name, + target_format=target_converter.format_name + ) + except Exception as e: + return ConversionResult( + success=False, + error=str(e), + source_format=self.format_name, + target_format=target_converter.format_name + ) + + def detect_format(self, filepath: str) -> str: + """Detect format from file extension. + + Args: + filepath: Path to file + + Returns: + Detected format name or None + """ + import os + ext = os.path.splitext(filepath)[1].lower() + format_map = { + '.json': 'json', + '.yaml': 'yaml', + '.yml': 'yaml', + '.toml': 'toml', + '.csv': 'csv', + } + return format_map.get(ext)