restore_graph_raw.bend

bendvy-ecs-core@0.1.0.0 · 124 lines · 0 definitions

1import Base
2import bendvy-ecs-core@0.1.0.0/decode_data.bend as D
3import bendvy-ecs-core@0.1.0.0/entity_key.bend as Key
4import bendvy-ecs-core@0.1.0.0/snapshot_data.bend as Snapshot
5import bendvy-ecs-core@0.1.0.0/restore_raw.bend as Basic
6import bendvy-ecs-core@0.1.0.0/restore_raw_number.bend as Number
7import bendvy-ecs-core@0.1.0.0/restore_graph_data.bend as Graph
8
9type Parsed is Data:
10  Accepted{snapshot:Graph.Snapshot}
11  Rejected{original:D.Raw,error:Basic.Error}
12def keys_tail(head:Key.Key,result:Basic.Decoded<List<&2,Key.Key>>) -> Basic.Decoded<List<&2,Key.Key>>:
13  match result:
14    case Basic.Value{tail}:Basic.Value{head <> tail}
15    case Basic.Failed{error}:Basic.Failed{error}
16def keys_head(next:Unit -> Basic.Decoded<List<&2,Key.Key>>,result:Basic.Decoded<Key.Key>) -> Basic.Decoded<List<&2,Key.Key>>:
17  match result:
18    case Basic.Value{head}:keys_tail(head,next(Unit{}))
19    case Basic.Failed{error}:Basic.Failed{error}
20def keys(+path:String,values:List<&2,D.Raw>,+index:U32) -> Basic.Decoded<List<&2,Key.Key>>:
21  match values:
22    case []:Basic.Value{[]}
23    case raw <> rest:keys_head((_ => keys(path,rest,U32.add(index,1))),Basic.key(path ++ "[" ++ U32.show(index) ++ "]",raw))
24def group_sources(target:Key.Key,result:Basic.Decoded<List<&2,Key.Key>>) -> Basic.Decoded<Graph.Group>:
25  match result:
26    case Basic.Value{sources}:Basic.Value{Graph.Group{target,sources}}
27    case Basic.Failed{error}:Basic.Failed{error}
28def group_target(path:String,raw:D.Raw,result:Basic.Decoded<Key.Key>) -> Basic.Decoded<Graph.Group>:
29  match raw result:
30    case _ Basic.Failed{error}:Basic.Failed{error}
31    case D.Array{sources} Basic.Value{target}:group_sources(target,keys(path,sources,0))
32    case other Basic.Value{_}:Basic.invalid(~Graph.Group,path,"array",other)
33def group(+path:String,raw:D.Raw) -> Basic.Decoded<Graph.Group>:
34  match raw:
35    case D.Array{[target,sources]}:group_target(path ++ "[1]",sources,Basic.key(path ++ "[0]",target))
36    case other:Basic.invalid(~Graph.Group,path,"target/sources pair",other)
37def groups_tail(head:Graph.Group,result:Basic.Decoded<List<&2,Graph.Group>>) -> Basic.Decoded<List<&2,Graph.Group>>:
38  match result:
39    case Basic.Value{tail}:Basic.Value{head <> tail}
40    case Basic.Failed{error}:Basic.Failed{error}
41def groups_head(next:Unit -> Basic.Decoded<List<&2,Graph.Group>>,result:Basic.Decoded<Graph.Group>) -> Basic.Decoded<List<&2,Graph.Group>>:
42  match result:
43    case Basic.Value{head}:groups_tail(head,next(Unit{}))
44    case Basic.Failed{error}:Basic.Failed{error}
45def groups(+path:String,values:List<&2,D.Raw>,+index:U32) -> Basic.Decoded<List<&2,Graph.Group>>:
46  match values:
47    case []:Basic.Value{[]}
48    case raw <> rest:groups_head((_ => groups(path,rest,U32.add(index,1))),group(path ++ "[" ++ U32.show(index) ++ "]",raw))
49def relation_groups(name:String,result:Basic.Decoded<List<&2,Graph.Group>>) -> Basic.Decoded<Graph.Relation>:
50  match result:
51    case Basic.Value{values}:Basic.Value{Graph.Relation{name,values}}
52    case Basic.Failed{error}:Basic.Failed{error}
53def relation(+name:String,raw:D.Raw) -> Basic.Decoded<Graph.Relation>:
54  match raw:
55    case D.Array{values}:relation_groups(name,groups("$.relations." ++ name,values,0))
56    case other:Basic.invalid(~Graph.Relation,"$.relations." ++ name,"array",other)
57def relations_tail(head:Graph.Relation,result:Basic.Decoded<List<&2,Graph.Relation>>) -> Basic.Decoded<List<&2,Graph.Relation>>:
58  match result:
59    case Basic.Value{tail}:Basic.Value{head <> tail}
60    case Basic.Failed{error}:Basic.Failed{error}
61def relations_head(next:Unit -> Basic.Decoded<List<&2,Graph.Relation>>,result:Basic.Decoded<Graph.Relation>) -> Basic.Decoded<List<&2,Graph.Relation>>:
62  match result:
63    case Basic.Value{head}:relations_tail(head,next(Unit{}))
64    case Basic.Failed{error}:Basic.Failed{error}
65def relations(fields:List<&2,D.Field>) -> Basic.Decoded<List<&2,Graph.Relation>>:
66  match fields:
67    case []:Basic.Value{[]}
68    case D.Field{name,raw} <> rest:relations_head((_ => relations(rest)),relation(name,raw))
69def machines(basic:Snapshot.Snapshot,relations:List<&2,Graph.Relation>,raw:D.Raw) -> Basic.Decoded<Graph.Snapshot>:
70  match raw:
71    case D.Object{fields}:Basic.Value{Graph.Snapshot{basic,relations,fields}}
72    case other:Basic.invalid(~Graph.Snapshot,"$.machines","object",other)
73def resources(next:U32,entities:List<&2,Snapshot.Entity>,relations:List<&2,Graph.Relation>,+fields:List<&2,D.Field>,raw:D.Raw) -> Basic.Decoded<Graph.Snapshot>:
74  match raw:
75    case D.Object{values}:machines(Snapshot.Snapshot{1,next,entities,values},relations,D.field("machines",fields))
76    case other:Basic.invalid(~Graph.Snapshot,"$.resources","object",other)
77def relations_checked(next:U32,entities:List<&2,Snapshot.Entity>,+fields:List<&2,D.Field>,result:Basic.Decoded<List<&2,Graph.Relation>>) -> Basic.Decoded<Graph.Snapshot>:
78  match result:
79    case Basic.Value{values}:resources(next,entities,values,fields,D.field("resources",fields))
80    case Basic.Failed{error}:Basic.Failed{error}
81def relation_object(next:U32,entities:List<&2,Snapshot.Entity>,fields:List<&2,D.Field>,raw:D.Raw) -> Basic.Decoded<Graph.Snapshot>:
82  match raw:
83    case D.Object{values}:relations_checked(next,entities,fields,relations(values))
84    case other:Basic.invalid(~Graph.Snapshot,"$.relations","object",other)
85def entities_checked(next:U32,+fields:List<&2,D.Field>,result:Basic.Decoded<List<&2,Snapshot.Entity>>) -> Basic.Decoded<Graph.Snapshot>:
86  match result:
87    case Basic.Value{values}:relation_object(next,values,fields,D.field("relations",fields))
88    case Basic.Failed{error}:Basic.Failed{error}
89def entity_array(next:U32,fields:List<&2,D.Field>,raw:D.Raw) -> Basic.Decoded<Graph.Snapshot>:
90  match raw:
91    case D.Array{values}:entities_checked(next,fields,Basic.entities(values,0))
92    case other:Basic.invalid(~Graph.Snapshot,"$.entities","array",other)
93def progress(+fields:List<&2,D.Field>,result:Basic.Decoded<U32>) -> Basic.Decoded<Graph.Snapshot>:
94  match result:
95    case Basic.Value{next}:entity_array(next,fields,D.field("entities",fields))
96    case Basic.Failed{error}:Basic.Failed{error}
97def version(+fields:List<&2,D.Field>,+raw:D.Raw,result:Number.Checked) -> Basic.Decoded<Graph.Snapshot>:
98  match result:
99    case Number.Value{1}:progress(fields,Basic.number("$.nextEntity",D.field("nextEntity",fields),True{}))
100    case _:Basic.Failed{Basic.UnsupportedVersion{raw}}
101def object(raw:D.Raw) -> Basic.Decoded<Graph.Snapshot>:
102  match raw:
103    case D.Object{+fields}:version(fields,D.field("version",fields),Number.checked(D.field("version",fields)))
104    case other:Basic.invalid(~Graph.Snapshot,"$","object",other)
105def finished(original:D.Raw,result:Basic.Decoded<Graph.Snapshot>) -> Parsed:
106  match result:
107    case Basic.Value{snapshot}:Accepted{snapshot}
108    case Basic.Failed{error}:Rejected{original,error}
109def parse(+raw:D.Raw) -> Parsed:finished(raw,object(raw))
110def saved_keys(values:List<&2,Key.Key>) -> List<&2,D.Raw>:
111  match values:
112    case []:[]
113    case key <> rest:Basic.saved_key(key) <> saved_keys(rest)
114def saved_groups(values:List<&2,Graph.Group>) -> List<&2,D.Raw>:
115  match values:
116    case []:[]
117    case Graph.Group{target,sources} <> rest:D.Array{[Basic.saved_key(target),D.Array{saved_keys(sources)}]} <> saved_groups(rest)
118def saved_relations(values:List<&2,Graph.Relation>) -> List<&2,D.Field>:
119  match values:
120    case []:[]
121    case Graph.Relation{name,groups} <> rest:D.Field{name,D.Array{saved_groups(groups)}} <> saved_relations(rest)
122def encode(value:Graph.Snapshot) -> D.Raw:
123  match value:
124    case Graph.Snapshot{Snapshot.Snapshot{version,next,entities,resources},relations,machines}:D.Object{[D.Field{"version",D.Number{version}},D.Field{"nextEntity",D.Number{next}},D.Field{"entities",D.Array{Basic.saved_entities(entities)}},D.Field{"relations",D.Object{saved_relations(relations)}},D.Field{"resources",D.Object{resources}},D.Field{"machines",D.Object{machines}}]}