|
1 | | -"""Integration with Rich for nicer CLI's!""" |
2 | | -from typing import Iterable, Union |
| 1 | +"""Integration with Rich. |
3 | 2 |
|
4 | | -from rich.tree import Tree |
5 | | - |
6 | | -from odin.exceptions import ValidationError, NON_FIELD_ERRORS |
7 | | - |
8 | | - |
9 | | -def _all_str(iterable: Iterable) -> bool: |
10 | | - """Does the supplied iterable only contain strings.""" |
11 | | - return all(isinstance(item, str) for item in iterable) |
12 | | - |
13 | | - |
14 | | -def _validation_error_to_tree(error_messages: Union[list, dict], tree: Tree): |
15 | | - """Internal recursive method.""" |
16 | | - |
17 | | - if isinstance(error_messages, dict): |
18 | | - for key, value in error_messages.items(): |
19 | | - |
20 | | - node = tree.add( |
21 | | - f"[yellow]:memo:" if key == NON_FIELD_ERRORS else f"[green]{key}" |
22 | | - ) |
23 | | - |
24 | | - _validation_error_to_tree(value, node) |
25 | | - |
26 | | - elif isinstance(error_messages, list): |
27 | | - if _all_str(error_messages): |
28 | | - for message in error_messages: |
29 | | - tree.add(f"[italic]{message}", guide_style="bold") |
30 | | - |
31 | | - else: |
32 | | - for idx, value in enumerate(error_messages): |
33 | | - node = tree.add(str(idx)) |
34 | | - _validation_error_to_tree(value, node) |
35 | | - |
36 | | - else: |
37 | | - # Shouldn't technically be possible with a valid error messages structure. |
38 | | - tree.add(f":warning: {error_messages}") |
39 | | - |
40 | | - |
41 | | -def validation_error_to_tree(error: ValidationError, *, tree: Tree = None) -> Tree: |
42 | | - """Map a validation error into a tree. |
43 | | -
|
44 | | - .. codeblock:: python |
45 | | -
|
46 | | - error_tree = validation_error_to_tree(error) |
47 | | - print(tree) |
48 | | -
|
49 | | - """ |
50 | | - tree = tree or Tree("[red bold]Validation Errors") |
51 | | - _validation_error_to_tree(error.error_messages, tree) |
52 | | - return tree |
| 3 | +https://rich.readthedocs.io/en/latest/index.html |
| 4 | +""" |
0 commit comments