119 lines
3.4 KiB
Python
119 lines
3.4 KiB
Python
"""Formatting module for config-converter-cli."""
|
|
|
|
import json
|
|
from typing import Any
|
|
|
|
from configconverter.converters import Converter
|
|
from configconverter.exceptions import IndentationError
|
|
|
|
|
|
class Formatter:
|
|
"""Handles pretty-printing and formatting of configuration files."""
|
|
|
|
VALID_INDENTS = (2, 4, 8)
|
|
|
|
def __init__(self):
|
|
self.converter = Converter()
|
|
|
|
def format(
|
|
self,
|
|
content: str,
|
|
indent: int = 2,
|
|
compact: bool = False,
|
|
format: str | None = None,
|
|
) -> str:
|
|
"""Format content with specified indentation.
|
|
|
|
Args:
|
|
content: The content to format
|
|
indent: Number of spaces for indentation (2, 4, or 8)
|
|
compact: Whether to use compact output (no extra whitespace)
|
|
format: Output format (json, yaml, toml). If None, detected from input.
|
|
|
|
Returns:
|
|
Formatted content
|
|
"""
|
|
if indent not in self.VALID_INDENTS:
|
|
raise IndentationError(
|
|
f"Invalid indentation: {indent}. Must be one of {self.VALID_INDENTS}"
|
|
)
|
|
|
|
input_format = self.converter.detect_format(content)
|
|
data = self.converter._parse(content, input_format)
|
|
|
|
if format is None:
|
|
output_format = input_format
|
|
else:
|
|
output_format = format
|
|
|
|
return self.converter.serialize_with_indent(data, output_format, indent, compact)
|
|
|
|
def to_json(
|
|
self, content: str, indent: int = 2, format: str | None = None
|
|
) -> str:
|
|
"""Convert content to JSON format.
|
|
|
|
Args:
|
|
content: The content to convert
|
|
indent: Number of spaces for indentation
|
|
format: Input format (if None, detected automatically)
|
|
|
|
Returns:
|
|
JSON formatted content
|
|
"""
|
|
if format:
|
|
data = self.converter._parse(content, format)
|
|
else:
|
|
detected = self.converter.detect_format(content)
|
|
data = self.converter._parse(content, detected)
|
|
|
|
return json.dumps(data, indent=indent, ensure_ascii=False)
|
|
|
|
def to_yaml(self, content: str, format: str | None = None) -> str:
|
|
"""Convert content to YAML format.
|
|
|
|
Args:
|
|
content: The content to convert
|
|
format: Input format (if None, detected automatically)
|
|
|
|
Returns:
|
|
YAML formatted content
|
|
"""
|
|
import io
|
|
from ruamel.yaml import YAML
|
|
|
|
if format:
|
|
data = self.converter._parse(content, format)
|
|
else:
|
|
detected = self.converter.detect_format(content)
|
|
data = self.converter._parse(content, detected)
|
|
|
|
yaml_parser = YAML()
|
|
yaml_parser.preserve_quotes = True
|
|
stream = io.StringIO()
|
|
yaml_parser.dump(data, stream)
|
|
return stream.getvalue()
|
|
|
|
def to_toml(self, content: str, format: str | None = None) -> str:
|
|
"""Convert content to TOML format.
|
|
|
|
Args:
|
|
content: The content to convert
|
|
format: Input format (if None, detected automatically)
|
|
|
|
Returns:
|
|
TOML formatted content
|
|
"""
|
|
import tomlkit
|
|
|
|
if format:
|
|
data = self.converter._parse(content, format)
|
|
else:
|
|
detected = self.converter.detect_format(content)
|
|
data = self.converter._parse(content, detected)
|
|
|
|
return tomlkit.dumps(data)
|
|
|
|
|
|
formatter = Formatter()
|