|
1
|
|
|
from typing import Union |
|
2
|
|
|
|
|
3
|
|
|
from jsons._common_impl import get_class_name, NoneType |
|
4
|
|
|
from jsons._compatibility_impl import get_union_params |
|
5
|
|
|
from jsons._dump_impl import dump |
|
6
|
|
|
from jsons.exceptions import JsonsError, SerializationError |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
def default_union_serializer(obj: object, cls: Union, **kwargs) -> object: |
|
10
|
|
|
""" |
|
11
|
|
|
Serialize an object to any matching type of the given union. The first |
|
12
|
|
|
successful serialization is returned. |
|
13
|
|
|
:param obj: The object that is to be serialized. |
|
14
|
|
|
:param cls: The Union type with a generic (e.g. Union[str, int]). |
|
15
|
|
|
:param kwargs: Any keyword arguments that are passed through the |
|
16
|
|
|
serialization process. |
|
17
|
|
|
:return: An object of the first type of the Union that could be |
|
18
|
|
|
serialized successfully. |
|
19
|
|
|
""" |
|
20
|
|
|
sub_types = get_union_params(cls) |
|
21
|
|
|
|
|
22
|
|
|
# Cater for Optional[...]/Union[None, ...] first to avoid blindly |
|
23
|
|
|
# string-ifying None in later serializers. |
|
24
|
|
|
if obj is None and NoneType in sub_types: |
|
25
|
|
|
return obj |
|
26
|
|
|
|
|
27
|
|
|
for sub_type in sub_types: |
|
28
|
|
|
try: |
|
29
|
|
|
return dump(obj, sub_type, **kwargs) |
|
30
|
|
|
except JsonsError: |
|
31
|
|
|
pass # Try the next one. |
|
32
|
|
|
else: |
|
33
|
|
|
args_msg = ', '.join([get_class_name(cls_) |
|
34
|
|
|
for cls_ in get_union_params(cls)]) |
|
35
|
|
|
err_msg = ('Could not match the object of type "{}" to any type of ' |
|
36
|
|
|
'the Union: {}'.format(type(obj), args_msg)) |
|
37
|
|
|
raise SerializationError(err_msg) |
|
38
|
|
|
|