Skip to content

Instantly share code, notes, and snippets.

@mjambon
Last active February 4, 2022 09:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjambon/1ece77adc9253acddaba0a837f17a34c to your computer and use it in GitHub Desktop.
Save mjambon/1ece77adc9253acddaba0a837f17a34c to your computer and use it in GitHub Desktop.
Current translation from everything.atd to everything.py done by atdpy
type kind = [
| Root (* class name conflict *)
| Thing of int
| WOW <json name="wow">
| Amaze <json name="!!!"> of string list
]
type root = {
id: string;
await: bool;
__init__: float;
items: int list list;
?maybe: int option;
~extras: int list;
~answer <python default="42">: int;
aliased: alias;
point: (float * float);
kinds: kind list;
(* TODO:
assoc: (string * int) list <json repr="object">;
map: (string * int) list <json repr="object"> <python repr="dict">;
*)
}
type alias = int list
"""Generated by atdpy from type definitions in everything.atd.
This implements classes for the types defined in 'everything.atd', providing
methods and functions to convert data from/to JSON.
"""
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, NoReturn, Optional, Tuple, Union
import json
############################################################################
# Private functions
############################################################################
def _atd_missing_json_field(type_name: str, json_field_name: str) -> NoReturn:
raise ValueError(f"missing field '{json_field_name}'"
f" in JSON object of type '{type_name}'")
def _atd_bad_json(expected_type: str, json_value: Any) -> NoReturn:
value_str = str(json_value)
if len(value_str) > 200:
value_str = value_str[:200] + '…'
raise ValueError(f"incompatible JSON value where"
f" type '{expected_type}' was expected: '{value_str}'")
def _atd_bad_python(expected_type: str, json_value: Any) -> NoReturn:
value_str = str(json_value)
if len(value_str) > 200:
value_str = value_str[:200] + '…'
raise ValueError(f"incompatible Python value where"
f" type '{expected_type}' was expected: '{value_str}'")
def _atd_read_unit(x: Any) -> None:
if x is None:
return x
else:
_atd_bad_json('unit', x)
def _atd_read_bool(x: Any) -> bool:
if isinstance(x, bool):
return x
else:
_atd_bad_json('bool', x)
def _atd_read_int(x: Any) -> int:
if isinstance(x, int):
return x
else:
_atd_bad_json('int', x)
def _atd_read_float(x: Any) -> float:
if isinstance(x, (int, float)):
return x
else:
_atd_bad_json('float', x)
def _atd_read_string(x: Any) -> str:
if isinstance(x, str):
return x
else:
_atd_bad_json('str', x)
def _atd_read_list(read_elt: Callable[[Any], Any]) \
-> Callable[[List[Any]], List[Any]]:
def read_list(elts: List[Any]) -> List[Any]:
if isinstance(elts, list):
return [read_elt(elt) for elt in elts]
else:
_atd_bad_json('array', elts)
return read_list
def _atd_read_nullable(read_elt: Callable[[Any], Any]) \
-> Callable[[Optional[Any]], Optional[Any]]:
def read_nullable(x: Any) -> Any:
if x is None:
return None
else:
return read_elt(x)
return read_nullable
def _atd_write_unit(x: Any) -> None:
if x is None:
return x
else:
_atd_bad_python('unit', x)
def _atd_write_bool(x: Any) -> bool:
if isinstance(x, bool):
return x
else:
_atd_bad_python('bool', x)
def _atd_write_int(x: Any) -> int:
if isinstance(x, int):
return x
else:
_atd_bad_python('int', x)
def _atd_write_float(x: Any) -> float:
if isinstance(x, (int, float)):
return x
else:
_atd_bad_python('float', x)
def _atd_write_string(x: Any) -> str:
if isinstance(x, str):
return x
else:
_atd_bad_python('str', x)
def _atd_write_list(write_elt: Callable[[Any], Any]) \
-> Callable[[List[Any]], List[Any]]:
def write_list(elts: List[Any]) -> List[Any]:
if isinstance(elts, list):
return [write_elt(elt) for elt in elts]
else:
_atd_bad_python('list', elts)
return write_list
def _atd_write_nullable(write_elt: Callable[[Any], Any]) \
-> Callable[[Optional[Any]], Optional[Any]]:
def write_nullable(x: Any) -> Any:
if x is None:
return None
else:
return write_elt(x)
return write_nullable
############################################################################
# Public classes
############################################################################
@dataclass
class Root_:
"""Original type: kind = [ ... | Root | ... ]"""
@property
def kind(self) -> str:
"""Name of the class representing this variant."""
return 'Root_'
@staticmethod
def to_json() -> Any:
return 'Root'
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class Thing:
"""Original type: kind = [ ... | Thing of ... | ... ]"""
value: int
@property
def kind(self) -> str:
"""Name of the class representing this variant."""
return 'Thing'
def to_json(self) -> Any:
return ['Thing', _atd_write_int(self.value)]
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class WOW:
"""Original type: kind = [ ... | WOW | ... ]"""
@property
def kind(self) -> str:
"""Name of the class representing this variant."""
return 'WOW'
@staticmethod
def to_json() -> Any:
return 'wow'
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class Amaze:
"""Original type: kind = [ ... | Amaze of ... | ... ]"""
value: List[str]
@property
def kind(self) -> str:
"""Name of the class representing this variant."""
return 'Amaze'
def to_json(self) -> Any:
return ['!!!', _atd_write_list(_atd_write_string)(self.value)]
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class Kind:
"""Original type: kind = [ ... ]"""
value: Union[Root_, Thing, WOW, Amaze]
@property
def kind(self) -> str:
"""Name of the class representing this variant."""
return self.value.kind
@classmethod
def from_json(cls, x: Any) -> 'Kind':
if isinstance(x, str):
if x == 'Root':
return cls(Root_())
if x == 'wow':
return cls(WOW())
_atd_bad_json('Kind', x)
if isinstance(x, List) and len(x) == 2:
cons = x[0]
if cons == 'Thing':
return cls(Thing(_atd_read_int(x[1])))
if cons == '!!!':
return cls(Amaze(_atd_read_list(_atd_read_string)(x[1])))
_atd_bad_json('Kind', x)
_atd_bad_json('Kind', x)
def to_json(self) -> Any:
return self.value.to_json()
@classmethod
def from_json_string(cls, x: str) -> 'Kind':
return cls.from_json(json.loads(x))
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class Alias:
"""Original type: alias"""
value: List[int]
@classmethod
def from_json(cls, x: Any) -> 'Alias':
return cls(_atd_read_list(_atd_read_int)(x))
def to_json(self) -> Any:
return _atd_write_list(_atd_write_int)(self.value)
@classmethod
def from_json_string(cls, x: str) -> 'Alias':
return cls.from_json(json.loads(x))
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
@dataclass
class Root:
"""Original type: root = { ... }"""
id: str
await_: bool
x___init__: float
items: List[List[int]]
extras: List[int]
aliased: Alias
point: Tuple[float, float]
kinds: List[Kind]
maybe: Optional[int] = None
answer: int = (42)
@classmethod
def from_json(cls, x: Any) -> 'Root':
if isinstance(x, dict):
return cls(
id=_atd_read_string(x['ID']) if 'ID' in x else _atd_missing_json_field('Root', 'ID'),
await_=_atd_read_bool(x['await']) if 'await' in x else _atd_missing_json_field('Root', 'await'),
x___init__=_atd_read_float(x['__init__']) if '__init__' in x else _atd_missing_json_field('Root', '__init__'),
items=_atd_read_list(_atd_read_list(_atd_read_int))(x['items']) if 'items' in x else _atd_missing_json_field('Root', 'items'),
extras=_atd_read_list(_atd_read_int)(x['extras']) if 'extras' in x else [],
aliased=Alias.from_json(x['aliased']) if 'aliased' in x else _atd_missing_json_field('Root', 'aliased'),
point=(lambda x: (_atd_read_float(x[0]), _atd_read_float(x[1])) if isinstance(x, list) else _atd_bad_json('array', x))(x['point']) if 'point' in x else _atd_missing_json_field('Root', 'point'),
kinds=_atd_read_list(Kind.from_json)(x['kinds']) if 'kinds' in x else _atd_missing_json_field('Root', 'kinds'),
maybe=_atd_read_int(x['maybe']) if 'maybe' in x else None,
answer=_atd_read_int(x['answer']) if 'answer' in x else (42),
)
else:
_atd_bad_json('Root', x)
def to_json(self) -> Any:
res: Dict[str, Any] = {}
res['ID'] = _atd_write_string(self.id)
res['await'] = _atd_write_bool(self.await_)
res['__init__'] = _atd_write_float(self.x___init__)
res['items'] = _atd_write_list(_atd_write_list(_atd_write_int))(self.items)
res['extras'] = _atd_write_list(_atd_write_int)(self.extras)
res['aliased'] = (lambda x: x.to_json())(self.aliased)
res['point'] = (lambda x: [_atd_write_float(x[0]), _atd_write_float(x[1])] if isinstance(x, tuple) else _atd_bad_python('tuple', x))(self.point)
res['kinds'] = _atd_write_list((lambda x: x.to_json()))(self.kinds)
if self.maybe is not None:
res['maybe'] = _atd_write_int(self.maybe)
res['answer'] = _atd_write_int(self.answer)
return res
@classmethod
def from_json_string(cls, x: str) -> 'Root':
return cls.from_json(json.loads(x))
def to_json_string(self, **kw: Any) -> str:
return json.dumps(self.to_json(), **kw)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment