1 import Base 2 import ./ordinary_declaration.bend as C 3 import ./decode_data.bend as D 4 5 # Trusted schema-author witness, not an unforgeable public constructor. 6 # Decoder describes untrusted DATA validation; no implicit Raw -> P inverse. 7 type Gate<-S:Data,-P:Type,-declaration:C.Declaration> is Type: 8 Transient{} 9 Persisted{codec:D.Codec,project:P -> P & D.Raw} 10 type Field is Data: 11 Omitted{name:String} 12 Saved{name:String,value:D.Raw} 13 def transient(~S:Data,~P:Type,~declaration:C.Declaration) -> Gate: 14 Transient{} 15 def persisted(~S:Data,~P:Type,~declaration:C.Declaration,codec:D.Codec,project:P -> P & D.Raw) -> Gate: 16 Persisted{codec,project} 17 def projected(~P:Type,name:String,observed:P & D.Raw) -> P & Field: 18 match observed: 19 case (owner,value):(owner,Saved{name,value}) 20 # Static eligibility mirrors TS Gate: export itself does not run its decoder. 21 # This low-level operation consumes Gate; snapshot-leaf reconstructs it from 22 # the retained ordinary declaration for repeated owner-preserving saves. 23 def export_owner(~S:Data,~P:Type,~declaration:C.Declaration,gate:Gate,owner:P) -> P & Field: 24 match gate: 25 case Transient{}:(owner,Omitted{C.key(~S,~P,declaration)}) 26 case Persisted{_,project}:projected(~P,C.key(~S,~P,declaration),project(owner))