state.bend

bendvy-ecs-core@0.1.0.3 · 55 lines · 13 definitions

1import Base
2import capabilities.bend as Cap
3import component.bend as C
4
5# Consumer-owned vocabulary, equality, legal move enum and endpoints are trusted
6# declarations. Local acceptance never commits the surrounding transaction.
7type WriteStatus<WriteError: Data> is Data:
8  WriteAccepted{}
9  WriteRejected{error: WriteError}
10type Outcome<Value: Data,WriteError: Data> is Data:
11  StateMoved{}
12  StateMismatch{expected: Value,actual: Value}
13  StateAccessRejected{access: C.Access<Value>}
14  StateWriteRejected{error: WriteError}
15def move_written(~H: Type,~Value: Data,~WriteError: Data,pair: H & WriteStatus<WriteError>) -> H & Outcome<Value,WriteError>:
16  match pair:
17    case (owner,WriteAccepted{}): (owner,StateMoved{})
18    case (owner,WriteRejected{error}): (owner,StateWriteRejected{error})
19def apply(~H: Type,~Value: Data,~WriteError: Data,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,+expected: Value,+target: Value,+actual: Value,owner: H,same: Bool) -> H & Outcome<Value,WriteError>:
20  match same:
21    case False{}: (owner,StateMismatch{expected,actual})
22    case True{}: move_written(~H,~Value,~WriteError,Cap.request(~H,~Value,~WriteStatus<WriteError>,~write,owner,target))
23def observed(~H: Type,~Value: Data,~WriteError: Data,~equal: Value -> Value -> Bool,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,+expected: Value,+target: Value,pair: H & C.Access<Value>) -> H & Outcome<Value,WriteError>:
24  match pair:
25    case (owner,C.Found{+actual}): apply(~H,~Value,~WriteError,~write,expected,target,actual,owner,equal(actual,expected))
26    case (owner,C.ComponentAbsent{}): (owner,StateAccessRejected{C.ComponentAbsent{}})
27    case (owner,C.MissingEntity{}): (owner,StateAccessRejected{C.MissingEntity{}})
28def compare_set(~H: Type,~Value: Data,~WriteError: Data,~equal: Value -> Value -> Bool,~read: Cap.Read<H,Value>,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,+expected: Value,+target: Value) -> H & Outcome<Value,WriteError>:
29  observed(~H,~Value,~WriteError,~equal,~write,expected,target,Cap.read(~H,~Value,~read,owner))
30def with_endpoints(~H: Type,~Value: Data,~WriteError: Data,~equal: Value -> Value -> Bool,~read: Cap.Read<H,Value>,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,pair: Value & Value) -> H & Outcome<Value,WriteError>:
31  (+expected,+target) = pair
32  compare_set(~H,~Value,~WriteError,~equal,~read,~write,owner,expected,target)
33def transition(~H: Type,~Value: Data,~Move: Data,~WriteError: Data,~equal: Value -> Value -> Bool,~endpoints: Move -> Value & Value,~read: Cap.Read<H,Value>,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,move: Move) -> H & Outcome<Value,WriteError>:
34  with_endpoints(~H,~Value,~WriteError,~equal,~read,~write,owner,endpoints(move))
35
36# Exact caller-error preservation; the caller's decoder validates its own Raw.
37# Returning Raw on refusal retains the supplied finite input independently of
38# whatever diagnostic representation the caller places inside Error.
39type TypedRawOutcome<Raw: Data,Error: Data,WriteError: Data> is Data:
40  TypedRawWritten{}
41  TypedRawRejected{raw: Raw,error: Error}
42  TypedRawWriteRejected{raw: Raw,error: WriteError}
43def written_result(~H: Type,~Raw: Data,~Error: Data,~WriteError: Data,raw: Raw,pair: H & WriteStatus<WriteError>) -> H & TypedRawOutcome<Raw,Error,WriteError>:
44  match pair:
45    case (owner,WriteAccepted{}): (owner,TypedRawWritten{})
46    case (owner,WriteRejected{error}): (owner,TypedRawWriteRejected{raw,error})
47def result_observed(~H: Type,~Value: Data,~Raw: Data,~Error: Data,~WriteError: Data,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,raw: Raw,decoded: Result<&2,&1,Error,Value>) -> H & TypedRawOutcome<Raw,Error,WriteError>:
48  match decoded:
49    case Done{value}: written_result(~H,~Raw,~Error,~WriteError,raw,Cap.request(~H,~Value,~WriteStatus<WriteError>,~write,owner,value))
50    case Fail{error}: (owner,TypedRawRejected{raw,error})
51def result_raw_inner(~H: Type,~Value: Data,~Raw: Data,~Error: Data,~WriteError: Data,~decode: Raw -> Result<&2,&1,Error,Value>,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,+raw: Raw) -> H & TypedRawOutcome<Raw,Error,WriteError>:
52  result_observed(~H,~Value,~Raw,~Error,~WriteError,~write,owner,raw,decode(raw))
53def set_raw_result(~H: Type,~Value: Data,~Raw: Data,~Error: Data,~WriteError: Data,~decode: Raw -> Result<&2,&1,Error,Value>,~write: Cap.Request<H,Value,WriteStatus<WriteError>>,owner: H,raw: Raw) -> H & TypedRawOutcome<Raw,Error,WriteError>:
54  match raw:
55    case +raw: result_raw_inner(~H,~Value,~Raw,~Error,~WriteError,~decode,~write,owner,raw)