Files
controller-wisetopdataserver/python/biopro/util/json.py
T
2021-12-20 14:52:55 +08:00

121 lines
3.0 KiB
Python

import abc
from pathlib import Path
from typing import Any, List, Dict, Union, TYPE_CHECKING
if TYPE_CHECKING:
JSON_OBJECT = Dict[str, 'JSON']
JSON_ARRAY = List['JSON']
JSON = Union[None, bool, int, float, str, 'JSON_ARRAY', 'JSON_OBJECT']
else:
JSON_OBJECT = Dict[str, Any]
JSON_ARRAY = List[Any]
JSON = Any
class JsonSerialize(metaclass=abc.ABCMeta):
__slots__ = ()
@abc.abstractmethod
def as_json(self) -> JSON:
"""class instance transform to json object.
:return: json object
"""
pass
@classmethod
def to_json(cls, json: Any):
"""object *json* to json format.
**mapping**
=============== ================
python type json type
=============== ================
None null
bool boolean
int int
float float
str String
list array
set set_object [1]_
dict object
JsonSerialize [2]_
=============== ================
.. [1] special object.
::
set_object = {
"set" : [value]
}
.. [2] call function :func:`as_json`
:param json: json object
:return: json object
:raises TypeError: object *json* not a :class:`JsonSerialize`
"""
if json is None:
return None
elif isinstance(json, (bool, int, float, str)):
return json
elif isinstance(json, list):
return [cls.to_json(j) for j in json]
elif isinstance(json, dict):
return {k: cls.to_json(j) for k, j in json.items()}
elif isinstance(json, set):
return {'set': list(json)}
elif isinstance(json, Path):
return str(json)
elif isinstance(json, JsonSerialize):
return json.as_json()
else:
raise TypeError('not a JsonSerialize : ' + type(json).__name__)
def str_json_value(value: JSON) -> str:
""" utility function to transform json to str value
:param value: json object
:return:
"""
if isinstance(value, bool):
return '1' if value else '0'
elif isinstance(value, int):
return str(value)
elif isinstance(value, str):
return value
elif isinstance(value, (list, tuple)):
return ','.join(map(str_json_value, value))
else:
raise RuntimeError('unsupported json form : ' + str(value))
def json_str_value(value: str) -> JSON:
"""utility function to try to transform str to json value
:param value:
:return: json value
"""
if ',' in value:
return list(map(json_str_value, value.split(',')))
else:
try:
if '.' in value:
return float(value)
else:
return int(value)
except ValueError:
return value