def decode(self, tpe: Type[Maybe], data: Json) -> Either[JsonError, Maybe[A]]: inner = Lists.wrap(tpe.__args__).head return (Right(Nothing) if data.absent else maybe_from_object( data, inner) if data.object else decode.match(data) / Just if data.array else Right(Nothing) if data.null else inner.cata( lambda a: decode_json_type_json(data, a) / Just, lambda: data.scalar.e(f'invalid type for `Maybe`: {data}', Maybe.check(data.data))))
def maybe_from_object(data: JsonObject, inner: Maybe[Type[A]]) -> Either[JsonError, Maybe[A]]: return (decode.match(data) / Just if data.has_type else inner.traverse( lambda a: decode_json_type_json(data, a), Either))
def decode(self, tpe: Type[Ident], data: Json) -> Either[JsonError, Ident[Any]]: return (decode_json_type_json(data, Key).lmap(List).accum_error_lift( decode_uuid_ident, data).accum_error_lift(decode_str_ident, data).accum_error_lift( ADTDecoder().decode, Ident, data))
def decode_str_ident(data: Json) -> Either[JsonError, StrIdent]: return decode_json_type_json(data, str) / StrIdent
def decode_uuid_ident(data: Json) -> Either[JsonError, UUIDIdent]: return decode_json_type_json(data, UUID) / UUIDIdent
def run(data: Json) -> Do: type_info = yield decode_json_type_json(data, TypeInfo) yield select_type(type_info)