Coverage for flowr / cli / output.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-05-22 18:42 +0000

1"""Output formatting for CLI results.""" 

2 

3import json 

4from typing import Any 

5 

6 

7def _format_dict_lines(data: dict[str, Any], indent: str = "") -> list[str]: 

8 """Format a single dict as key-value lines.""" 

9 lines: list[str] = [] 

10 for key, value in data.items(): 

11 if isinstance(value, list): 

12 if not value: 

13 lines.append(f"{indent}{key}: (none)") 

14 elif isinstance(value[0], dict): 

15 lines.append(f"{indent}{key}:") 

16 for item in value: 

17 first = True 

18 for k, v in item.items(): 

19 if first: 

20 lines.append(f"{indent} - {k}: {v}") 

21 first = False 

22 else: 

23 lines.append(f"{indent} {k}: {v}") 

24 else: 

25 for item in value: 

26 lines.append(f"{indent}{key}: {item}") 

27 elif isinstance(value, dict): 

28 lines.append(f"{indent}{key}:") 

29 lines.extend(_format_dict_lines(value, indent + " ")) 

30 else: 

31 lines.append(f"{indent}{key}: {value}") 

32 return lines 

33 

34 

35def format_text(result: dict[str, Any] | list[dict[str, Any]]) -> str: 

36 """Format a result dict or list of dicts as human-readable text.""" 

37 if isinstance(result, list): 

38 lines: list[str] = [] 

39 for item in result: 

40 lines.extend(_format_dict_lines(item)) 

41 lines.append("---") 

42 if lines: 

43 lines.pop() 

44 return "\n".join(lines) 

45 return "\n".join(_format_dict_lines(result)) 

46 

47 

48def format_json(result: Any) -> str: # noqa: ANN401 

49 """Format a result as JSON.""" 

50 return json.dumps(result, indent=2)