"""Base converter class and factory for format-specific converters.""" from abc import ABC, abstractmethod from typing import Any, Dict, List, Optional class Converter(ABC): """Abstract base class for format converters.""" @property @abstractmethod def name(self) -> str: """Return the format name.""" pass @abstractmethod def loads(self, data: str) -> Dict[str, Any]: """Parse a string into a dictionary.""" pass @abstractmethod def dumps(self, data: Dict[str, Any], indent: Optional[int] = None) -> str: """Serialize a dictionary to a string.""" pass @abstractmethod def load(self, file_path: str) -> Dict[str, Any]: """Read and parse a file.""" pass @abstractmethod def dump(self, data: Dict[str, Any], file_path: str, indent: Optional[int] = None) -> None: """Serialize and write to a file.""" pass class ConverterFactory: """Factory for creating format-specific converters.""" _converters: Dict[str, Converter] = {} @classmethod def register(cls, format_name: str, converter: Converter) -> None: """Register a converter for a format.""" cls._converters[format_name.lower()] = converter @classmethod def get(cls, format_name: str) -> Converter: """Get a converter for the specified format.""" format_lower = format_name.lower() if format_lower not in cls._converters: raise ValueError(f"Unsupported format: {format_name}") return cls._converters[format_lower] @classmethod def supported_formats(cls) -> List[str]: """Return list of supported format names.""" return list(cls._converters.keys()) @classmethod def is_supported(cls, format_name: str) -> bool: """Check if a format is supported.""" return format_name.lower() in cls._converters