1 import Base 2 import schedule_provision.bend as Provision 3 4 # Trusted declaration metadata carries no provider, World or callback grant. 5 type Resource is Data: 6 Resource{id:U32,name:String} 7 type Metadata is Data: 8 Metadata{name:String,requirements:List<&2,Resource>} 9 type Definition<-S:Data,-Plan:Type> is Type: 10 Definition{metadata:Metadata,plan:Plan} 11 12 def token(~S:Data,value:Resource) -> Provision.Requirement: 13 match value: 14 case Resource{id,_}:Provision.Resource{id} 15 def tokens(~S:Data,values:List<&2,Resource>) -> List<&2,Provision.Requirement>: 16 match values: 17 case []:[] 18 case value <> rest:token(~S,value) <> tokens(~S,rest) 19 def choose_first(~S:Data,matched:Bool,value:Resource,alternative:Maybe<&2,Resource>) -> Maybe<&2,Resource>: 20 match matched: 21 case True{}:Some{value} 22 case False{}:alternative 23 def first(~S:Data,+id:U32,values:List<&2,Resource>) -> Maybe<&2,Resource>: 24 match values: 25 case []:None{} 26 case +value <> rest: 27 match value: 28 case Resource{key,_}: 29 choose_first(~S,U32.is_eq(id,key),value,first(~S,id,rest)) 30 def keep(~S:Data,value:Maybe<&2,Resource>,rest:List<&2,Resource>) -> List<&2,Resource>: 31 match value: 32 case None{}:rest 33 case Some{value}:value <> rest 34 # Internal keys are lowered exclusively from Resource; wider provision token 35 # cases have no source entry and confer no category/provider capability. 36 def names(~S:Data,keys:List<&2,Provision.Requirement>,+values:List<&2,Resource>) -> List<&2,Resource>: 37 match keys: 38 case []:[] 39 case Provision.Resource{id} <> rest:keep(~S,first(~S,id,values),names(~S,rest,values)) 40 case _ <> rest:names(~S,rest,values) 41 def normalize(~S:Data,+values:List<&2,Resource>) -> List<&2,Resource>: 42 names(~S,Provision.unique(~S,tokens(~S,values)),values) 43 def make(~S:Data,~Plan:Type,name:String,requirements:List<&2,Resource>,plan:Plan) -> Definition: 44 Definition{Metadata{name,normalize(~S,requirements)},plan} 45 def read(~S:Data,~Plan:Type,definition:Definition) -> Definition & Metadata: 46 match definition: 47 case Definition{+metadata,plan}:(Definition{metadata,plan},metadata) 48 def into_plan(~S:Data,~Plan:Type,definition:Definition) -> Plan: 49 match definition: 50 case Definition{_,plan}:plan 51 def kind(~S:Data,metadata:Metadata) -> String: 52 "inspector" 53 def name(~S:Data,metadata:Metadata) -> String: 54 match metadata: 55 case Metadata{name,_}:name 56 def requirements(~S:Data,metadata:Metadata) -> List<&2,Resource>: 57 match metadata: 58 case Metadata{_,requirements}:requirements