Coverage for src/typedal/serializers/as_json.py: 100%
15 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 16:34 +0200
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 16:34 +0200
1"""
2Replacement for pydal's json serializer.
3"""
5import json
6import typing
7from typing import Any
9from configurablejson import ConfigurableJsonEncoder, JSONRule
12class SerializedJson(ConfigurableJsonEncoder):
13 """
14 Custom encoder class with slightly improved defaults.
15 """
17 def _default(self, o: Any) -> Any: # pragma: no cover
18 if hasattr(o, "as_dict"):
19 return o.as_dict()
20 elif hasattr(o, "asdict"):
21 return o.asdict()
22 elif hasattr(o, "_asdict"):
23 return o._asdict()
24 elif hasattr(o, "_as_dict"):
25 return o._as_dict()
26 elif hasattr(o, "to_dict"):
27 return o.to_dict()
28 elif hasattr(o, "todict"):
29 return o.todict()
30 elif hasattr(o, "_todict"):
31 return o._todict()
32 elif hasattr(o, "_to_dict"):
33 return o._to_dict()
34 elif hasattr(o, "__json__"):
35 if callable(o.__json__):
36 return o.__json__()
37 else:
38 return o.__json__
39 elif hasattr(o, "__dict__"):
40 return o.__dict__
42 return str(o)
44 @typing.overload
45 def rules(self, o: Any, with_default: typing.Literal[False]) -> JSONRule | None:
46 """
47 If you pass with_default=False, you could get a None result.
48 """
50 @typing.overload
51 def rules(self, o: Any, with_default: typing.Literal[True] = True) -> JSONRule:
52 """
53 If you don't pass with_default=False, you will always get a JSONRule result.
54 """
56 def rules(self, o: Any, with_default: bool = True) -> JSONRule | None:
57 """
58 Custom rules, such as set to list and as_dict/__json__ etc. lookups.
59 """
60 _type = type(o)
62 _rules: dict[type[Any], JSONRule] = {
63 # convert set to list
64 set: JSONRule(preprocess=lambda o: list(o)),
65 }
67 # other rules:
68 return _rules.get(_type, JSONRule(transform=self._default) if with_default else None)
71def encode(something: Any, indent: int = None, **kw: Any) -> str:
72 """
73 Encode anything to JSON with some improved defaults.
74 """
75 return json.dumps(something, indent=indent, cls=SerializedJson, **kw)