state.bend
bendvy-ecs-core@0.1.0.0 · 55 lines · 0 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)