"""JSON persistence of the existing domain objects; never pickle or a new memo schema.""" from dataclasses import asdict import json from .disposition import Actor, ActorKind, Disposition, Verb from .memo import (BindingLevel, BindingSlice, Highlight, Identifier, Memo, PacketItem, Principal, Scope, StepKind) from .presentation import Phase, Presentation from .provenance import Claim, Route def dumps(value) -> str: return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False, allow_nan=False, default=lambda x: sorted(x) if isinstance(x, frozenset) else asdict(x)) def memo_from(data: dict) -> Memo: data = dict(data) binding = dict(data["binding"]) principal = dict(binding["principal"]) principal["identifiers"] = tuple(Identifier(**i) for i in principal.get("identifiers", [])) binding["principal"] = Principal(**principal) binding["target"] = Scope(**binding["target"]) data["binding"] = BindingSlice(**binding) data["binding_level"] = BindingLevel(data["binding_level"]) data["step_kind"] = StepKind(data["step_kind"]) data["packet"] = tuple(PacketItem(**p) for p in data["packet"]) data["highlights"] = tuple(Highlight(**h) for h in data["highlights"]) return Memo(**data) def presentation_from(data: dict) -> Presentation: data = dict(data) data["phase"] = Phase(data["phase"]) data["acked_highlight_ids"] = frozenset(data["acked_highlight_ids"]) for field in ("tenant", "principal_type"): if data[field] is not None: data[field] = Claim(data[field]["value"], Route(data[field]["route"])) return Presentation(**data) def disposition_from(data: dict) -> Disposition: data = dict(data) data["verb"] = Verb(data["verb"]) data["actor"] = Actor(data["actor"]["sub"], ActorKind(data["actor"]["kind"])) data["reasons"] = tuple(data["reasons"]) return Disposition(**data)