Add converter modules (JSON, YAML, TOML, CSV)
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
117
src/converters/base.py
Normal file
117
src/converters/base.py
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user