1 import Base 2 import ./ordinary_schema.bend as Schema 3 import ./ordinary_declaration.bend as Identity 4 import ./ordinary_component_binding.bend as Component 5 import ./resource_field_binding.bend as Resource 6 import ./owner_product.bend as Product 7 import ./column.bend as Col 8 # The physical product paths follow the ordinary component/resource schema tree. 9 # Applications supply identities and opaque-value projections, not debug lenses. 10 # Trusted setup identities for this fixed one-component, one-resource schema. 11 type Declarations<-S:Data,-Payload:Type,-Counter:Type> is Data: 12 Declarations{component:Identity.Declaration,resource:Schema.Resource} 13 # Nominal component-binding token; it carries no payload or runtime permission. 14 type Token<-S:Data,-Payload:Type> is Data: 15 Token{} 16 # Physical component owner type for this fixed schema adapter. 17 def store(~S:Data,~Payload:Type) -> Type: 18 Product.Owner,Unit> 19 # Physical resource owner type for this fixed schema adapter. 20 def resources(~Counter:Type) -> Type: 21 Product.Owner 22 # Assemble the component/resource schema from their supplied identities. 23 # This adapter fixes product paths; it is not a general schema generator. 24 def schema(~S:Data,~Payload:Type,~Counter:Type,declarations:Declarations) -> Schema.Schema: 25 match declarations: 26 case Declarations{component,resource}:Schema.product(~S,~Col.Column,~Unit,~Unit,~Counter,Schema.component(~S,~Payload,component),Schema.resource_schema(~S,~Counter,resource)) 27 # Trusted product projection: consume the store and return its remainder and 28 # component column for reassembly with component_put. 29 def component_take(~S:Data,~Payload:Type,value:store(~S,~Payload)) -> Unit & Col.Column: 30 Product.take(~Col.Column,~Unit,Product.Left{},value) 31 # Reassemble the store from the projected remainder and component column. 32 def component_put(~S:Data,~Payload:Type,rest:Unit,value:Col.Column) -> store(~S,~Payload): 33 Product.put(~Col.Column,~Unit,Product.Left{},rest,value) 34 # Recover the component declaration used by this schema adapter. 35 def component_identity(~S:Data,~Payload:Type,~Counter:Type,declarations:Declarations) -> Identity.Declaration: 36 match declarations: 37 case Declarations{identity,_}:identity 38 # Build the component binding for the fixed product path. The supplied view 39 # is a trusted affine payload projection returning an owner and detached Data; 40 # this constructor does not establish projection purity or owner identity. 41 def component_binding(~S:Data,~Payload:Type,~Counter:Type,~V:Data,~view:Payload -> Payload & V,~declarations:Declarations) -> Component.Binding,component_take(~S,~Payload),component_put(~S,~Payload),view>: 42 Component.bind(~S,~store(~S,~Payload),~Unit,~Payload,~V,~Token,~component_take(~S,~Payload),~component_put(~S,~Payload),~view,component_identity(~S,~Payload,~Counter,declarations)) 43 # Recover the resource declaration used by this schema adapter. 44 def resource_identity(~S:Data,~Payload:Type,~Counter:Type,declarations:Declarations) -> Schema.Resource: 45 match declarations: 46 case Declarations{_,identity}:identity 47 # Trusted lens selecting the resource in the fixed right product field. 48 def counter_lens(~Counter:Type) -> Product.Lens: 49 Product.lens(~Unit,~Counter,~Product.Right{}) 50 # Build the resource binding from the fixed lens and supplied declaration. 51 # This setup binding does not itself grant a system read or write access. 52 def resource_binding(~S:Data,~Payload:Type,~Counter:Type,~declarations:Declarations) -> Resource.Binding: 53 Resource.Binding{}