| 19 | |
| 20 | |
| 21 | def to_json_compatible(value: Any) -> Any: |
| 22 | if value is None or isinstance(value, (bool, int, float, str)): |
| 23 | return value |
| 24 | if isinstance(value, bytes): |
| 25 | return {_BYTES_MARKER: base64.b64encode(value).decode("ascii")} |
| 26 | if isinstance(value, datetime): |
| 27 | return {_DATETIME_MARKER: value.isoformat()} |
| 28 | if isinstance(value, collections.abc.Mapping): |
| 29 | return {str(k): to_json_compatible(v) for k, v in value.items()} |
| 30 | if isinstance(value, (list, tuple, set, frozenset)): |
| 31 | return [to_json_compatible(v) for v in value] |
| 32 | if isinstance(value, collections.abc.Iterable): |
| 33 | return [to_json_compatible(v) for v in value] |
| 34 | raise TypeError(f"Value of type {type(value).__name__} is not JSON serializable") |
| 35 | |
| 36 | |
| 37 | def from_json_compatible(value: Any) -> Any: |