diff --git a/config_auditor/parsers.py b/config_auditor/parsers.py new file mode 100644 index 0000000..8c86427 --- /dev/null +++ b/config_auditor/parsers.py @@ -0,0 +1,74 @@ +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