diff --git a/cmdparse/formatters.py b/cmdparse/formatters.py new file mode 100644 index 0000000..27a31d8 --- /dev/null +++ b/cmdparse/formatters.py @@ -0,0 +1,83 @@ +"""Output formatting for JSON/CSV/YAML formats.""" + +import json +import csv +import io +from typing import List, Dict, Any + + +def format_json(data: List[Dict[str, Any]], pretty: bool = True) -> str: + """Format parsed data as JSON.""" + if pretty: + return json.dumps(data, indent=2, ensure_ascii=False) + return json.dumps(data, ensure_ascii=False) + + +def format_yaml(data: List[Dict[str, Any]]) -> str: + """Format parsed data as YAML.""" + import yaml + + class SafeLineBreakDumper(yaml.SafeDumper): + def write_line_break(self, data=None): + super().write_line_break(data) + + try: + return yaml.dump(data, Dumper=SafeLineBreakDumper, default_flow_style=False, allow_unicode=True) + except Exception: + return yaml.dump(data, default_flow_style=False, allow_unicode=True) + + +def format_csv(data: List[Dict[str, Any]]) -> str: + """Format parsed data as CSV.""" + if not data: + return "" + + output = io.StringIO() + if data: + fieldnames = list(data[0].keys()) + writer = csv.DictWriter(output, fieldnames=fieldnames) + writer.writeheader() + writer.writerows(data) + + return output.getvalue() + + +def format_raw(data: List[Dict[str, Any]]) -> str: + """Format parsed data as raw text (simple representation).""" + if not data: + return "" + + lines = [] + for i, row in enumerate(data): + if isinstance(row, dict): + for key, value in row.items(): + lines.append(f"{key}: {value}") + else: + lines.append(str(row)) + + return '\n'.join(lines) + + +def format_data(data: List[Dict[str, Any]], output_format: str) -> str: + """ + Format parsed data into specified output format. + + Args: + data: List of dictionaries to format + output_format: Format to use ('json', 'csv', 'yaml', 'raw') + + Returns: + Formatted string output + """ + format_lower = output_format.lower() if output_format else 'json' + + if format_lower == 'json': + return format_json(data) + elif format_lower == 'yaml': + return format_yaml(data) + elif format_lower == 'csv': + return format_csv(data) + elif format_lower == 'raw': + return format_raw(data) + else: + return format_json(data)