dependency_composer.bend
bendvy-ecs-core@0.1.0.3 · 50 lines · 11 definitions
1import Base
2import bendvy-ecs-core@0.1.0.3/dependency_composer_program.bend as Scoped
3import bendvy-ecs-core@0.1.0.3/dependency_plan.bend as Plan
4import bendvy-ecs-core@0.1.0.3/schema_fragments.bend as Fragment
5import bendvy-ecs-core@0.1.0.3/execution_declaration.bend as D
6
7type Error is Data:
8 Schema{error:Fragment.Error}
9 Schedule{error:Plan.Invalid<String>}
10 Nesting{error:Scoped.NestError}
11def first_error(first:Maybe<&2,Error>,second:Maybe<&2,Error>) -> Maybe<&2,Error>:
12 match first:
13 case Some{error}:Some{error}
14 case None{}:second
15def schema_error(value:Fragment.Validation) -> Maybe<&2,Error>:
16 match value:
17 case Fragment.Valid{}:None{}
18 case Fragment.Invalid{error}:Some{Schema{error}}
19def schedule_error(value:Maybe<&2,Plan.Invalid<String>>) -> Maybe<&2,Error>:
20 match value:
21 case None{}:None{}
22 case Some{error}:Some{Schedule{error}}
23def kind_key(kind:Fragment.RegistryKind,key:String) -> String:
24 match kind:
25 case Fragment.Component{}:D.requirement_key(D.ComponentAccess{},key)
26 case Fragment.Resource{}:D.requirement_key(D.ResourceAccess{},key)
27 case Fragment.Service{}:D.requirement_key(D.ServiceAccess{},key)
28 case Fragment.Event{}:"event/" ++ key
29 case Fragment.Relation{}:"relation/" ++ key
30def entry_key(~S:Data,entry:Fragment.Entry<S>) -> String:
31 match entry:
32 case Fragment.Entry{kind,key,_}:kind_key(kind,key)
33 case Fragment.Classified{kind,key,_,_}:kind_key(kind,key)
34def provides(~S:Data,entries:List<&2,Fragment.Entry<S>>,+key:String) -> Bool:
35 match entries:
36 case []:False{}
37 case entry <> rest:Bool.or(String.eq(entry_key(~S,entry),key),provides(~S,rest,key))
38def missing_step(available:Bool,id:U32,key:String,next:Maybe<&2,Plan.Invalid<String>>) -> Maybe<&2,Plan.Invalid<String>>:
39 match available:
40 case True{}:next
41 case False{}:Some{Plan.Missing{id,key}}
42def missing_needs(~S:Data,needs:List<&2,String>,+entries:List<&2,Fragment.Entry<S>>,+id:U32) -> Maybe<&2,Plan.Invalid<String>>:
43 match needs:
44 case []:None{}
45 case +key <> rest:missing_step(provides(~S,entries,key),id,key,missing_needs(~S,rest,entries,id))
46def missing(~S:Data,nodes:List<&2,Plan.Node<String>>,+entries:List<&2,Fragment.Entry<S>>) -> Maybe<&2,Plan.Invalid<String>>:
47 match nodes:
48 case []:None{}
49 case Plan.Node{id,needs} <> rest:Plan.first_error(~String,missing_needs(~S,needs,entries,id),missing(~S,rest,entries))
50def available(key:String) -> Bool:True{}