execution_lifetime_scope_coverage.bend

bendvy-ecs-core@0.1.0.3 · 86 lines · 15 definitions

1import Base
2import bendvy-ecs-core@0.1.0.3/execution_command_permission.bend as Permission
3import bendvy-ecs-core@0.1.0.3/execution_composer_layout.bend as Layout
4import bendvy-ecs-core@0.1.0.3/execution_resource_policy.bend as Policy
5import bendvy-ecs-core@0.1.0.3/execution_relation_resource_snapshot.bend as Snapshot
6import bendvy-ecs-core@0.1.0.3/execution_relation_failure_retention.bend as Retention
7
8# Cleanup may mutate every declared relation family. It refuses before mutation
9# if the accepted catalogue omits any protected graph in the actual root layout.
10def contains(~S:Data,~resources:Layout.Layout,+route:Layout.Route,relations:Permission.Relations<S,resources>) -> Bool:
11  match relations:
12    case Permission.NoRelations{}:False{}
13    case Permission.RelationAllowed{selected,_,_,_,_,_,rest}:Bool.or(Permission.same_route(route,selected),contains(~S,~resources,route,rest))
14    case Permission.ScopeAllowed{_,_,_,_,_,rest}:contains(~S,~resources,route,rest)
15def append(prefix:Layout.Route,+suffix:Layout.Route) -> Layout.Route:
16  match prefix:
17    case Layout.AtLeaf{}:suffix
18    case Layout.InLeft{rest}:Layout.InLeft{append(rest,suffix)}
19    case Layout.InRight{rest}:Layout.InRight{append(rest,suffix)}
20def leaf(~S:Data,~resources:Layout.Layout,policy:Policy.Policy,route:Layout.Route,relations:Permission.Relations<S,resources>) -> Bool:
21  match policy:
22    case Policy.ProtectedRelation{_,_}:contains(~S,~resources,route,relations)
23    case Policy.Ordinary{}:True{}
24    case Policy.ProtectedLifetimeScope{_}:True{}
25def layout(~S:Data,~resources:Layout.Layout,current:Layout.Layout,+prefix:Layout.Route,+relations:Permission.Relations<S,resources>) -> Bool:
26  match current:
27    case Layout.EmptyLayout{}:True{}
28    case Layout.LayoutLeaf{_,_,_,_,policy}:leaf(~S,~resources,policy,prefix,relations)
29    case Layout.ClassifiedLayoutLeaf{_,_,_,_,_,policy}:leaf(~S,~resources,policy,prefix,relations)
30    case Layout.LayoutPair{left,right}:Bool.and(layout(~S,~resources,left,append(prefix,Layout.InLeft{Layout.AtLeaf{}}),relations),layout(~S,~resources,right,append(prefix,Layout.InRight{Layout.AtLeaf{}}),relations))
31def namespaces(~S:Data,+namespace:U32,views:List<&2,Snapshot.GraphView<S>>) -> Bool:
32  match views:
33    case []:True{}
34    case Snapshot.GraphView{_,_,stored,_} <> rest:Bool.and(U32.is_eq(namespace,stored),namespaces(~S,namespace,rest))
35
36def scope_contains(-S:Data,-resources:Layout.Layout,+route:Layout.Route,relations:Permission.Relations<S,resources>) -> Bool:
37  match relations:
38    case Permission.NoRelations{}:False{}
39    case Permission.RelationAllowed{_,_,_,_,_,_,rest}:scope_contains(S,resources,route,rest)
40    case Permission.ScopeAllowed{selected,_,_,_,_,rest}:Bool.or(Permission.same_route(route,selected),scope_contains(S,resources,route,rest))
41def scopes_leaf(-S:Data,-resources:Layout.Layout,policy:Policy.Policy,route:Layout.Route,relations:Permission.Relations<S,resources>) -> Bool:
42  match policy:
43    case Policy.ProtectedLifetimeScope{_}:scope_contains(S,resources,route,relations)
44    case Policy.ProtectedRelation{_,_}:True{}
45    case Policy.Ordinary{}:True{}
46def scopes_layout(-S:Data,-resources:Layout.Layout,current:Layout.Layout,+prefix:Layout.Route,+relations:Permission.Relations<S,resources>) -> Bool:
47  match current:
48    case Layout.EmptyLayout{}:True{}
49    case Layout.LayoutLeaf{_,_,_,_,policy}:scopes_leaf(S,resources,policy,prefix,relations)
50    case Layout.ClassifiedLayoutLeaf{_,_,_,_,_,policy}:scopes_leaf(S,resources,policy,prefix,relations)
51    case Layout.LayoutPair{left,right}:Bool.and(scopes_layout(S,resources,left,append(prefix,Layout.InLeft{Layout.AtLeaf{}}),relations),scopes_layout(S,resources,right,append(prefix,Layout.InRight{Layout.AtLeaf{}}),relations))
52def scope_routes(-S:Data,-resources:Layout.Layout,relations:Permission.Relations<S,resources>) -> List<&2,Layout.Route>:
53  match relations:
54    case Permission.NoRelations{}:[]
55    case Permission.RelationAllowed{_,_,_,_,_,_,rest}:scope_routes(S,resources,rest)
56    case Permission.ScopeAllowed{route,_,_,_,_,rest}:route <> scope_routes(S,resources,rest)
57def protected_leaf(policy:Policy.Policy) -> Bool:
58  match policy:
59    case Policy.ProtectedRelation{_,_}:True{}
60    case Policy.ProtectedLifetimeScope{_}:True{}
61    case Policy.Ordinary{}:False{}
62def has_protected(current:Layout.Layout) -> Bool:
63  match current:
64    case Layout.EmptyLayout{}:False{}
65    case Layout.LayoutLeaf{_,_,_,_,policy}:protected_leaf(policy)
66    case Layout.ClassifiedLayoutLeaf{_,_,_,_,_,policy}:protected_leaf(policy)
67    case Layout.LayoutPair{left,right}:Bool.or(has_protected(left),has_protected(right))
68def provisioned_leaf(policy:Policy.Policy,route:Layout.Route,graphs:List<&2,Layout.Route>,scopes:List<&2,Layout.Route>) -> Bool:
69  match policy:
70    case Policy.Ordinary{}:True{}
71    case Policy.ProtectedRelation{_,_}:Retention.contains(route,graphs)
72    case Policy.ProtectedLifetimeScope{_}:Retention.contains(route,scopes)
73def provisioned_layout(current:Layout.Layout,+prefix:Layout.Route,+graphs:List<&2,Layout.Route>,+scopes:List<&2,Layout.Route>) -> Bool:
74  match current:
75    case Layout.EmptyLayout{}:True{}
76    case Layout.LayoutLeaf{_,_,_,_,policy}:provisioned_leaf(policy,prefix,graphs,scopes)
77    case Layout.ClassifiedLayoutLeaf{_,_,_,_,_,policy}:provisioned_leaf(policy,prefix,graphs,scopes)
78    case Layout.LayoutPair{left,right}:Bool.and(provisioned_layout(left,append(prefix,Layout.InLeft{Layout.AtLeaf{}}),graphs,scopes),provisioned_layout(right,append(prefix,Layout.InRight{Layout.AtLeaf{}}),graphs,scopes))
79def cleanup_complete(~S:Data,~resources:Layout.Layout,+relations:Permission.Relations<S,resources>,routes:Maybe<&2,Permission.CleanupRoutes>) -> Bool:
80  match routes:
81    case None{}:Bool.and(layout(~S,~resources,resources,Layout.AtLeaf{},relations),scopes_layout(S,resources,resources,Layout.AtLeaf{},relations))
82    case Some{Permission.CleanupRoutes{graphs,scopes}}:provisioned_layout(resources,Layout.AtLeaf{},graphs,scopes)
83def cleanup_scopes(-S:Data,-resources:Layout.Layout,relations:Permission.Relations<S,resources>,routes:Maybe<&2,Permission.CleanupRoutes>) -> List<&2,Layout.Route>:
84  match routes:
85    case None{}:scope_routes(S,resources,relations)
86    case Some{Permission.CleanupRoutes{_,scopes}}:scopes