framework/
inner.rs

1use catalogue::Catalogue;
2use parse::{
3    Map,
4    UpperName,
5};
6use parse::xml::*;
7use roxmltree::{
8    Node,
9};
10
11mod choice;
12mod classification;
13mod ddl;
14mod dotted;
15mod suggest;
16mod table;
17
18pub use choice::{
19	Choice,
20	ChoiceItem,
21};
22pub use classification::{
23    Classification,
24    ClassificationFolder,
25};
26pub (crate) use dotted::{
27    DottedField,
28    DottedRefer,
29    DottedReverse,
30};
31pub (crate) use suggest::{
32    Suggest,
33};
34pub use table::{
35    BooleanDisplayAs,
36    BooleanField,
37    Field,
38    Index,
39    IndexKind,
40    IdentifierField,
41    NumberField,
42    NumberRange,
43    ReferField,
44    ReferKind,
45    StringField,
46    StringKind,
47    Table,
48};
49pub (crate) use table::{
50    AddressField,
51    ChoiceField,
52    ClassificationField,
53    ClassificationRestrict,
54    FieldKind,
55    ReferRestrict,
56    ReferRestrictTo,
57    Summary,
58};
59
60use crate::{
61	ChoiceId,
62	ClassificationId,
63	Error,
64	TableId,
65};
66
67use crate::pass0::Framework0;
68
69pub struct Framework {
70    pub (crate) choices: Map<UpperName, Choice, ChoiceId>,
71    pub (crate) classifications: Map<UpperName, Classification, ClassificationId>,
72    pub (crate) tables: Map<UpperName, Table, TableId>,
73    pub version: usize,
74}
75
76impl Framework {
77    pub (crate) fn parse(
78        element: Node,
79        catalogue: Catalogue,
80        errors: &mut Vec<Error>,
81    ) -> Option<Self> {
82        let Some(framework0) = Framework0::parse(element, catalogue, errors) else {
83            return None;
84        };
85
86        let Some(choices) = framework0.choices.map(Choice::map, errors) else {
87            return None;
88        };
89        let Some(classifications) = framework0.classifications.map_cx(Classification::map, &framework0, errors) else {
90            return None;
91        };
92        let Some(tables) = framework0.tables.map_cx(Table::map, &framework0, errors) else {
93            return None;
94        };
95
96        let version = framework0.version;
97        let framework = Framework {
98            choices,
99            classifications,
100            tables,
101            version: version.number,
102        };
103
104        match framework.ddl_hash() {
105            Ok(hash) =>
106                if hash != version.hash {
107                    errors.push(Error::HashChanged {
108                        calculated: hash,
109                        existing: version.hash_range.into(),
110                    });
111
112                    return None;
113                }
114
115            Err(message) => {
116                errors.push(Error::HashError {
117                    message,
118                });
119
120                return None;
121            }
122        }
123
124        Some(framework)
125    }
126
127    pub (crate) fn choice_by_id(&self, id: &ChoiceId) -> &Choice {
128        self.choices.vec.get(id.index())
129            .expect("Exist by construction")
130    }
131
132    pub (crate) fn classification_by_id(&self, id: &ClassificationId) -> &Classification {
133        self.classifications.vec.get(id.index())
134            .expect("Exist by construction")
135    }
136
137    pub (crate) fn table_by_id(&self, id: &TableId) -> &Table {
138        self.tables.vec.get(id.index())
139            .expect("Exist by construction")
140    }
141}