diff --git a/config_convert/converters/toml_converter.py b/config_convert/converters/toml_converter.py new file mode 100644 index 0000000..fccc7e7 --- /dev/null +++ b/config_convert/converters/toml_converter.py @@ -0,0 +1,63 @@ +"""TOML format converter using tomli/tomllib.""" + +import sys +from pathlib import Path +from typing import Any, Dict, Optional + +from config_convert.converters.base import Converter + +if sys.version_info >= (3, 11): + import tomllib +else: + import tomli as tomllib + + +class TOMLConverter(Converter): + """Converter for TOML format.""" + + @property + def name(self) -> str: + return "toml" + + def loads(self, data: str) -> Dict[str, Any]: + return tomllib.loads(data) + + def dumps(self, data: Dict[str, Any], indent: Optional[int] = None) -> str: + output = [] + self._write_dict(data, output, indent=0) + return "\n".join(output) + + def _write_dict(self, data: Dict[str, Any], output: list, indent: int) -> None: + for key, value in data.items(): + if isinstance(value, dict): + output.append(f"[{key}]") + self._write_dict(value, output, indent + 1) + elif isinstance(value, list): + if len(value) > 0 and isinstance(value[0], dict): + for item in value: + output.append(f"[[{key}]]") + self._write_dict(item, output, indent + 1) + else: + items_str = ", ".join(self._format_value(item) for item in value) + output.append(f"{key} = [{items_str}]") + else: + output.append(f"{key} = {self._format_value(value)}") + + def _format_value(self, value: Any) -> str: + if isinstance(value, bool): + return "true" if value else "false" + elif isinstance(value, str): + return f'"{value}"' + elif value is None: + return "" + else: + return str(value) + + def load(self, file_path: str) -> Dict[str, Any]: + with open(file_path, "rb") as f: + return tomllib.load(f) + + def dump(self, data: Dict[str, Any], file_path: str, indent: Optional[int] = None) -> None: + Path(file_path).parent.mkdir(parents=True, exist_ok=True) + with open(file_path, "wb") as f: + f.write(self.dumps(data).encode("utf-8"))