diff --git a/config_converter/converters/yaml_converter.py b/config_converter/converters/yaml_converter.py new file mode 100644 index 0000000..70f8c18 --- /dev/null +++ b/config_converter/converters/yaml_converter.py @@ -0,0 +1,49 @@ +"""YAML format converter.""" + +from pathlib import Path +from typing import Any, Dict + +import yaml + +from config_converter.converters.base import BaseConverter, ConversionError + + +class YamlConverter(BaseConverter): + """Converter for YAML configuration files.""" + + FORMAT_NAME = "yaml" + FILE_EXTENSIONS = ["yaml", "yml"] + + def read(self, source: str | Path) -> Dict[str, Any]: + """Read and parse a YAML configuration file.""" + try: + with open(source, "r", encoding="utf-8") as f: + return yaml.safe_load(f) or {} + except yaml.YAMLError as e: + raise ConversionError(f"Invalid YAML in {source}: {e}") from e + except FileNotFoundError as e: + raise ConversionError(f"File not found: {source}") from e + except PermissionError as e: + raise ConversionError(f"Permission denied: {source}") from e + + def write(self, data: Dict[str, Any], target: str | Path) -> None: + """Write configuration data to a YAML file.""" + try: + with open(target, "w", encoding="utf-8") as f: + yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False) + except (OSError, TypeError) as e: + raise ConversionError(f"Failed to write YAML to {target}: {e}") from e + + def parse(self, content: str) -> Dict[str, Any]: + """Parse YAML content from a string.""" + try: + return yaml.safe_load(content) or {} + except yaml.YAMLError as e: + raise ConversionError(f"Invalid YAML content: {e}") from e + + def format(self, data: Dict[str, Any]) -> str: + """Format configuration data to a YAML string.""" + try: + return yaml.dump(data, default_flow_style=False, allow_unicode=True, sort_keys=False) + except (TypeError, ValueError) as e: + raise ConversionError(f"Failed to format data as YAML: {e}") from e