Skip to main content

src/javascript_data_files/encoder.py

1"""
2Pure functions for converting Python values to JavaScript strings.
4We prioritise human-readability over absolute efficiency.
5For example, JSON is nicely indented to be more readable, rather than
6a compact encoding that uses less bytes on disk.
7"""
9import json
10import typing
13class HumanReadableEncoder(json.JSONEncoder):
14 """
15 A custom JSON encoder with a few niceties for human-readability.
16 """
18 def encode(self, o: typing.Any) -> str:
19 """
20 Return a JSON string representation of a Python data structure, o.
21 """
22 if isinstance(o, list) and len(o) < 7 and len(json.dumps(o)) < 60:
23 return json.dumps(o)
25 return super().encode(o)
28def encode_as_json(
29 value: typing.Any, *, ensure_ascii: bool = False, sort_keys: bool = False
30) -> str:
31 """
32 Convert a Python value to a JSON-encoded string.
33 """
34 return json.dumps(
35 value,
36 indent=2,
37 sort_keys=sort_keys,
38 ensure_ascii=ensure_ascii,
39 cls=HumanReadableEncoder,
40 )
43def encode_as_js(
44 value: typing.Any,
45 varname: str,
46 *,
47 ensure_ascii: bool = False,
48 sort_keys: bool = False,
49) -> str:
50 """
51 Convert a Python value to a JSON-encoded JavaScript value.
52 """
53 json_string = encode_as_json(value, ensure_ascii=ensure_ascii, sort_keys=sort_keys)
54 js_string = f"const {varname} = {json_string};\n"
56 return js_string