from abc import ABC, abstractmethod from typing import Any, Dict, Optional import json import toml import yaml class Parser(ABC): @abstractmethod def parse(self, content: str) -> Optional[Dict[str, Any]]: pass @abstractmethod def dump(self, data: Dict[str, Any]) -> str: pass class JsonParser(Parser): def parse(self, content: str) -> Optional[Dict[str, Any]]: try: return json.loads(content) except json.JSONDecodeError: return None def dump(self, data: Dict[str, Any]) -> str: return json.dumps(data, indent=2) class YamlParser(Parser): def parse(self, content: str) -> Optional[Dict[str, Any]]: try: return yaml.safe_load(content) except yaml.YAMLError: return None def dump(self, data: Dict[str, Any]) -> str: return yaml.dump(data, default_flow_style=False) class TomlParser(Parser): def parse(self, content: str) -> Optional[Dict[str, Any]]: try: return toml.loads(content) except toml.TomlDecodeError: return None def dump(self, data: Dict[str, Any]) -> str: return toml.dumps(data) class ParserFactory: PARSERS = { "json": JsonParser, "yaml": YamlParser, "toml": TomlParser, } def get_parser(self, format_type: str) -> Optional[Parser]: parser_class = self.PARSERS.get(format_type.lower()) if parser_class: return parser_class() return None def parse(self, format_type: str, content: str) -> Optional[Dict[str, Any]]: parser = self.get_parser(format_type) if parser: return parser.parse(content) return None def dump(self, format_type: str, data: Dict[str, Any]) -> Optional[str]: parser = self.get_parser(format_type) if parser: return parser.dump(data) return None