framework/
lib.rs

1use camino::Utf8Path;
2use catalogue::Catalogue;
3use parse::xml;
4use parse::xml::*;
5use std::ops::Deref;
6
7mod error;
8mod id;
9pub mod inner;
10mod pass0;
11
12pub use error::Error;
13use id::*;
14pub use inner::{
15    Framework,
16};
17
18pub fn parse<P: AsRef<Utf8Path>>(path: P, catalogue: Catalogue)
19    -> Result<Framework, ParseErrors<Error>>
20{
21    xml::parse(path, move |element, errors| {
22        Framework::parse(element, catalogue, errors)
23    })
24}
25
26pub struct AddressField<'a> {
27    framework: &'a Framework,
28    table: &'a inner::Table,
29    address: &'a inner::AddressField,
30}
31
32impl<'a> AddressField<'a> {
33    pub fn address1(&self) -> Field<'a> {
34        Field {
35            framework: self.framework,
36            table: self.table,
37            field: &self.table.field_by_id(&self.address.address1),
38        }
39    }
40
41    pub fn address2(&self) -> Field<'a> {
42        Field {
43            framework: self.framework,
44            table: self.table,
45            field: &self.table.field_by_id(&self.address.address2),
46        }
47    }
48
49    pub fn country(&self) -> Field<'a> {
50        Field {
51            framework: self.framework,
52            table: self.table,
53            field: &self.table.field_by_id(&self.address.country),
54        }
55    }
56
57    pub fn postcode(&self) -> Field<'a> {
58        Field {
59            framework: self.framework,
60            table: self.table,
61            field: &self.table.field_by_id(&self.address.postcode),
62        }
63    }
64
65    pub fn state(&self) -> Field<'a> {
66        Field {
67            framework: self.framework,
68            table: self.table,
69            field: &self.table.field_by_id(&self.address.state),
70        }
71    }
72
73    pub fn suburb(&self) -> Field<'a> {
74        Field {
75            framework: self.framework,
76            table: self.table,
77            field: &self.table.field_by_id(&self.address.suburb),
78        }
79    }
80}
81
82pub struct BooleanField<'a> {
83    boolean: &'a inner::BooleanField,
84}
85
86impl<'a> Deref for BooleanField<'a> {
87    type Target = inner::BooleanField;
88
89    fn deref(&self) -> &Self::Target {
90        self.boolean
91    }
92}
93
94pub struct Choice<'a> {
95    framework: &'a Framework,
96    choice: &'a inner::Choice,
97}
98
99impl<'a> Deref for Choice<'a> {
100    type Target = inner::Choice;
101
102    fn deref(&self) -> &Self::Target {
103        self.choice
104    }
105}
106
107impl<'a> Choice<'a> {
108    pub fn items(&self) -> ChoiceItems<'_> {
109        ChoiceItems {
110            framework: self.framework,
111            choice: self.choice,
112            iter: self.choice.items.vec.iter(),
113        }
114    }
115}
116
117pub struct Choices<'a> {
118    framework: &'a Framework,
119    iter: std::slice::Iter<'a, inner::Choice>,
120}
121
122impl<'a> Iterator for Choices<'a> {
123    type Item = Choice<'a>;
124
125    fn next(&mut self) -> Option<Self::Item> {
126        if let Some(choice) = self.iter.next() {
127            Some(Choice {
128                framework: self.framework,
129                choice,
130            })
131        } else {
132            None
133        }
134    }
135}
136
137pub struct ChoiceField<'a> {
138    framework: &'a Framework,
139    choice: &'a inner::ChoiceField,
140}
141
142impl<'a> Deref for ChoiceField<'a> {
143    type Target = inner::ChoiceField;
144
145    fn deref(&self) -> &Self::Target {
146        self.choice
147    }
148}
149
150impl<'a> ChoiceField<'a> {
151    pub fn choice(&self) -> Choice<'a> {
152        Choice {
153            framework: self.framework,
154            choice: &self.framework.choice_by_id(&self.choice.choice),
155        }
156    }
157}
158
159pub struct ChoiceItem<'a> {
160    framework: &'a Framework,
161    choice: &'a inner::Choice,
162    item: &'a inner::ChoiceItem,
163}
164
165impl<'a> Deref for ChoiceItem<'a> {
166    type Target = inner::ChoiceItem;
167
168    fn deref(&self) -> &Self::Target {
169        self.item
170    }
171}
172
173impl<'a> ChoiceItem<'a> {
174    pub fn choice(&self) -> Choice<'a> {
175        Choice {
176            framework: self.framework,
177            choice: self.choice,
178        }
179    }
180}
181
182pub struct ChoiceItems<'a> {
183    framework: &'a Framework,
184    choice: &'a inner::Choice,
185    iter: std::slice::Iter<'a, inner::ChoiceItem>,
186}
187
188impl<'a> Iterator for ChoiceItems<'a> {
189    type Item = ChoiceItem<'a>;
190
191    fn next(&mut self) -> Option<Self::Item> {
192        if let Some(item) = self.iter.next() {
193            Some(ChoiceItem {
194                framework: self.framework,
195                choice: self.choice,
196                item,
197            })
198        } else {
199            None
200        }
201    }
202}
203
204#[derive(Copy, Clone)]
205pub enum ChoiceSortBy {
206    Occurance,
207    Title,
208}
209
210pub struct Classification<'a> {
211    framework: &'a Framework,
212    classification: &'a inner::Classification,
213}
214
215impl<'a> Deref for Classification<'a> {
216    type Target = inner::Classification;
217
218    fn deref(&self) -> &Self::Target {
219        self.classification
220    }
221}
222
223impl<'a> Classification<'a> {
224    pub fn has_national_limit(&self) -> Option<Classification<'a>> {
225        if let Some(id) = &self.classification.has_national_limit {
226            Some(Classification {
227                framework: self.framework,
228                classification: self.framework.classification_by_id(id),
229            })
230        } else {
231            None
232        }
233    }
234
235    pub fn has_national_set(&self) -> Option<Classification<'a>> {
236        if let Some(id) = &self.classification.has_national_set {
237            Some(Classification {
238                framework: self.framework,
239                classification: &self.framework.classification_by_id(id),
240            })
241        } else {
242            None
243        }
244    }
245}
246
247pub struct Classifications<'a> {
248    framework: &'a Framework,
249    iter: std::slice::Iter<'a, inner::Classification>,
250}
251
252impl<'a> Iterator for Classifications<'a> {
253    type Item = Classification<'a>;
254
255    fn next(&mut self) -> Option<Self::Item> {
256        if let Some(classification) = self.iter.next() {
257            Some(Classification {
258                framework: self.framework,
259                classification,
260            })
261        } else {
262            None
263        }
264    }
265}
266
267pub struct ClassificationField<'a> {
268    framework: &'a Framework,
269    table: &'a inner::Table,
270    classification: &'a inner::ClassificationField,
271}
272
273impl<'a> ClassificationField<'a> {
274    pub fn classification(&self) -> Classification<'a> {
275        Classification {
276            framework: self.framework,
277            classification: &self.framework.classification_by_id(&self.classification.classification),
278        }
279    }
280
281    pub fn restrict(&self) -> Option<ClassificationRestrict<'a>> {
282        match &self.classification.restrict {
283            Some(inner::ClassificationRestrict::State(state)) =>
284                Some(ClassificationRestrict::State(
285                    DottedField::new(self.framework, self.table, state)
286                )),
287
288            Some(inner::ClassificationRestrict::National(national)) =>
289                Some(ClassificationRestrict::National(
290                    DottedField::new(self.framework, self.table, national)
291                )),
292
293            None =>
294                None,
295        }
296    }
297}
298
299pub enum ClassificationRestrict<'a> {
300    State(DottedField<'a>),
301    National(DottedField<'a>),
302}
303
304#[derive(Copy, Clone)]
305pub enum CustomSave {
306    Both,
307    Did,
308    None,
309    Plan,
310    Will,
311}
312
313pub enum DottedField<'a> {
314    Field(Field<'a>),
315    Refer(DottedRefer<'a>),
316    Reverse(DottedReverse<'a>),
317}
318
319impl<'a> DottedField<'a> {
320    fn new(
321        framework: &'a Framework,
322        table: &'a inner::Table,
323        dotted: &'a inner::DottedField,
324    ) -> Self {
325        match dotted {
326            inner::DottedField::Field(field) =>
327                DottedField::Field(Field {
328                    framework,
329                    table,
330                    field: table.field_by_id(field),
331                }),
332
333            inner::DottedField::Refer(refer) =>
334                DottedField::Refer(DottedRefer {
335                    framework,
336                    table,
337                    refer,
338                }),
339
340            inner::DottedField::Reverse(reverse) =>
341                DottedField::Reverse(DottedReverse {
342                    framework,
343                    reverse,
344                }),
345        }
346    }
347}
348
349impl<'a> std::fmt::Display for DottedField<'a> {
350    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
351        match self {
352            DottedField::Field(field) =>
353                write!(f, "{}", field.name),
354
355            DottedField::Refer(refer) =>
356                write!(f, "{}.{}", refer.field().name, refer.dot()),
357
358            DottedField::Reverse(reverse) =>
359                if let Some(dot) = reverse.dot() {
360                    write!(f, "{}.{}", reverse.table().name, dot)
361                } else {
362                    write!(f, "{}", reverse.table().name)
363                }
364        }
365    }
366}
367
368pub struct DottedRefer<'a> {
369    framework: &'a Framework,
370    table: &'a inner::Table,
371    refer: &'a inner::DottedRefer,
372}
373
374impl<'a> DottedRefer<'a> {
375    pub fn dot(&self) -> DottedField<'a> {
376        DottedField::new(
377            self.framework,
378            self.framework.table_by_id(&self.refer.refer),
379            &self.refer.dot,
380        )
381    }
382
383    pub fn field(&self) -> Field<'a> {
384        let field = self.table.field_by_id(&self.refer.field);
385
386        Field {
387            framework: self.framework,
388            table: self.table,
389            field,
390        }
391    }
392
393    pub fn table(&self) -> Table<'a> {
394        Table {
395            framework: self.framework,
396            table: self.table,
397        }
398    }
399}
400
401pub struct DottedReverse<'a> {
402    framework: &'a Framework,
403    reverse: &'a inner::DottedReverse,
404}
405
406impl<'a> DottedReverse<'a> {
407    pub fn dot(&self) -> Option<DottedField<'a>> {
408        if let Some(dot) = &self.reverse.dot {
409            Some(DottedField::new(
410                self.framework,
411                self.framework.table_by_id(&self.reverse.reverse),
412                dot,
413            ))
414        } else {
415            None
416        }
417    }
418
419    pub fn field(&self) -> Field<'a> {
420        let table = self.framework.table_by_id(&self.reverse.reverse);
421        let field = table.field_by_id(&self.reverse.field);
422
423        Field {
424            framework: self.framework,
425            table,
426            field,
427        }
428    }
429
430    pub fn table(&self) -> Table<'a> {
431        let table = self.framework.table_by_id(&self.reverse.reverse);
432
433        Table {
434            framework: self.framework,
435            table,
436        }
437    }
438}
439
440pub struct Field<'a> {
441    framework: &'a Framework,
442    table: &'a inner::Table,
443    field: &'a inner::Field,
444}
445
446impl<'a> Deref for Field<'a> {
447    type Target = inner::Field;
448
449    fn deref(&self) -> &Self::Target {
450        self.field
451    }
452}
453
454impl<'a> Field<'a> {
455    pub fn kind(&self) -> FieldKind<'a> {
456        match &self.field.kind {
457            inner::FieldKind::Address(address) =>
458                FieldKind::Address(AddressField {
459                    framework: self.framework,
460                    table: self.table,
461                    address,
462                }),
463
464            inner::FieldKind::Alias(alias) =>
465                FieldKind::Alias(DottedField::new(self.framework, self.table, alias)),
466
467            inner::FieldKind::Binary => FieldKind::Binary,
468
469            inner::FieldKind::Boolean(boolean) =>
470                FieldKind::Boolean(BooleanField {
471                    boolean,
472                }),
473
474            inner::FieldKind::Choice(choice) =>
475                FieldKind::Choice(ChoiceField {
476                    framework: self.framework,
477                    choice,
478                }),
479
480            inner::FieldKind::Classification(classification) =>
481                FieldKind::Classification(ClassificationField {
482                    framework: self.framework,
483                    table: self.table,
484                    classification,
485                }),
486
487            inner::FieldKind::Content => FieldKind::Content,
488            inner::FieldKind::Date => FieldKind::Date,
489            inner::FieldKind::EFTSL => FieldKind::EFTSL,
490            inner::FieldKind::Formula => FieldKind::Formula,
491
492            inner::FieldKind::Identifier(identifier) =>
493                FieldKind::Identifier(IdentifierField {
494                    identifier,
495                }),
496
497            inner::FieldKind::Memo => FieldKind::Memo,
498            inner::FieldKind::Money => FieldKind::Money,
499            inner::FieldKind::Names => FieldKind::Names,
500            inner::FieldKind::Number(number) =>
501                FieldKind::Number(NumberField {
502                    number,
503                }),
504
505            inner::FieldKind::Percent => FieldKind::Percent,
506
507            inner::FieldKind::Refer(refer) =>
508                FieldKind::Refer(ReferField {
509                    framework: self.framework,
510                    table: self.table,
511                    refer,
512                }),
513
514            inner::FieldKind::Sequence => FieldKind::Sequence,
515
516            inner::FieldKind::String(string) =>
517                FieldKind::String(StringField {
518                    string,
519                }),
520
521            inner::FieldKind::Time => FieldKind::Time,
522        }
523    }
524
525    pub fn table(&self) -> Table<'a> {
526        Table {
527            framework: self.framework,
528            table: self.table,
529        }
530    }
531}
532
533pub struct Fields<'a> {
534    framework: &'a Framework,
535    table: &'a inner::Table,
536    iter: std::slice::Iter<'a, inner::Field>,
537}
538
539impl<'a> Iterator for Fields<'a> {
540    type Item = Field<'a>;
541
542    fn next(&mut self) -> Option<Self::Item> {
543        if let Some(field) = self.iter.next() {
544            Some(Field {
545                framework: self.framework,
546                table: self.table,
547                field,
548            })
549        } else {
550            None
551        }
552    }
553}
554
555pub struct FieldsById<'a> {
556    framework: &'a Framework,
557    table: &'a inner::Table,
558    iter: std::slice::Iter<'a, FieldId>,
559}
560
561impl<'a> Iterator for FieldsById<'a> {
562    type Item = Field<'a>;
563
564    fn next(&mut self) -> Option<Self::Item> {
565        if let Some(field) = self.iter.next() {
566            Some(Field {
567                framework: self.framework,
568                table: self.table,
569                field: self.table.field_by_id(field),
570            })
571        } else {
572            None
573        }
574    }
575}
576
577pub enum FieldKind<'a> {
578    Address(AddressField<'a>),
579    Alias(DottedField<'a>),
580    Binary,
581    Boolean(BooleanField<'a>),
582    Choice(ChoiceField<'a>),
583    Classification(ClassificationField<'a>),
584    Content,
585    Date,
586    Formula,
587    EFTSL,
588    Identifier(IdentifierField<'a>),
589    Memo,
590    Money,
591    Names,
592    Number(NumberField<'a>),
593    Percent,
594    Refer(ReferField<'a>),
595    Sequence,
596    String(StringField<'a>),
597    Time,
598}
599
600impl Framework {
601    pub fn choices(&self) -> Choices<'_> {
602        Choices {
603            framework: self,
604            iter: self.choices.vec.iter(),
605        }
606    }
607
608    pub fn classifications(&self) -> Classifications<'_> {
609        Classifications {
610            framework: self,
611            iter: self.classifications.vec.iter(),
612        }
613    }
614
615    pub fn tables(&self) -> Tables<'_> {
616        Tables {
617            framework: self,
618            iter: self.tables.vec.iter(),
619        }
620    }
621}
622
623pub struct IdentifierField<'a> {
624    identifier: &'a inner::IdentifierField,
625}
626
627impl<'a> Deref for IdentifierField<'a> {
628    type Target = inner::IdentifierField;
629
630    fn deref(&self) -> &Self::Target {
631        self.identifier
632    }
633}
634
635pub struct Index<'a> {
636    framework: &'a Framework,
637    table: &'a inner::Table,
638    index: &'a inner::Index,
639}
640
641impl<'a> Deref for Index<'a> {
642    type Target = inner::Index;
643
644    fn deref(&self) -> &Self::Target {
645        self.index
646    }
647}
648
649impl<'a> Index<'a> {
650    pub fn fields(&self) -> FieldsById<'_> {
651        FieldsById {
652            framework: self.framework,
653            table: self.table,
654            iter: self.index.fields.iter(),
655        }
656    }
657
658    pub fn table(&self) -> Table<'a> {
659        Table {
660            framework: self.framework,
661            table: self.table,
662        }
663    }
664}
665
666pub struct Indexes<'a> {
667    framework: &'a Framework,
668    table: &'a inner::Table,
669    iter: std::slice::Iter<'a, inner::Index>,
670}
671
672impl<'a> Iterator for Indexes<'a> {
673    type Item = Index<'a>;
674
675    fn next(&mut self) -> Option<Self::Item> {
676        if let Some(index) = self.iter.next() {
677            Some(Index {
678                framework: self.framework,
679                table: self.table,
680                index,
681            })
682        } else {
683            None
684        }
685    }
686}
687
688pub struct NumberField<'a> {
689    number: &'a inner::NumberField,
690}
691
692impl<'a> Deref for NumberField<'a> {
693    type Target = inner::NumberField;
694
695    fn deref(&self) -> &Self::Target {
696        self.number
697    }
698}
699
700pub struct ReferField<'a> {
701    framework: &'a Framework,
702    table: &'a inner::Table,
703    refer: &'a inner::ReferField,
704}
705
706impl<'a> Deref for ReferField<'a> {
707    type Target = inner::ReferField;
708
709    fn deref(&self) -> &Self::Target {
710        self.refer
711    }
712}
713
714impl<'a> ReferField<'a> {
715    pub fn refer(&self) -> Table<'a> {
716        Table {
717            framework: self.framework,
718            table: self.framework.table_by_id(&self.refer.refer),
719        }
720    }
721
722    pub fn restrict(&self) -> Option<ReferRestrict<'a>> {
723        match &self.refer.restrict {
724            Some(restrict) =>
725                Some(ReferRestrict {
726                    framework: self.framework,
727                    table: self.table,
728                    refer: self.refer,
729                    restrict,
730                }),
731
732            None =>
733                None,
734        }
735    }
736}
737
738pub struct ReferRestrict<'a> {
739    framework: &'a Framework,
740    table: &'a inner::Table,
741    refer: &'a inner::ReferField,
742    restrict: &'a inner::ReferRestrict,
743}
744
745impl<'a> ReferRestrict<'a> {
746    pub fn field(&self) -> DottedField<'a> {
747        let table = self.framework.table_by_id(&self.refer.refer);
748
749        DottedField::new(self.framework, table, &self.restrict.field)
750    }
751
752    pub fn value(&self) -> ReferRestrictTo<'a> {
753        match &self.restrict.value {
754            inner::ReferRestrictTo::Field(field) =>
755                ReferRestrictTo::Field(DottedField::new(self.framework, self.table, field)),
756
757            inner::ReferRestrictTo::Table =>
758                ReferRestrictTo::Table,
759        }
760    }
761}
762
763pub enum ReferRestrictTo<'a> {
764    Field(DottedField<'a>),
765    Table,
766}
767
768pub struct StringField<'a> {
769    string: &'a inner::StringField,
770}
771
772impl<'a> Deref for StringField<'a> {
773    type Target = inner::StringField;
774
775    fn deref(&self) -> &Self::Target {
776        self.string
777    }
778}
779
780pub struct Summary<'a> {
781    framework: &'a Framework,
782    table: &'a inner::Table,
783    summary: &'a inner::Summary,
784}
785
786impl<'a> Summary<'a> {
787    pub fn fields(&self) -> FieldsById<'_> {
788        FieldsById {
789            framework: self.framework,
790            table: self.table,
791            iter: self.summary.fields.iter(),
792        }
793    }
794
795    pub fn table(&self) -> Table<'a> {
796        Table {
797            framework: self.framework,
798            table: self.table,
799        }
800    }
801}
802
803pub enum Suggest<'a> {
804    Choice {
805        choice: DottedField<'a>,
806    },
807    IdentifierAndName {
808        identifier: DottedField<'a>,
809        name: DottedField<'a>,
810    },
811    IdentifierAndNames {
812        identifier: DottedField<'a>,
813        names: DottedField<'a>,
814    },
815    Name {
816        name: DottedField<'a>,
817    },
818    Names {
819        names: DottedField<'a>,
820    },
821}
822
823pub struct Table<'a> {
824    framework: &'a Framework,
825    table: &'a inner::Table,
826}
827
828impl<'a> Deref for Table<'a> {
829    type Target = inner::Table;
830
831    fn deref(&self) -> &Self::Target {
832        self.table
833    }
834}
835
836impl<'a> Table<'a> {
837    pub fn fields(&self) -> Fields<'_> {
838        Fields {
839            framework: self.framework,
840            table: self.table,
841            iter: self.table.fields.vec.iter(),
842        }
843    }
844
845    pub fn indexes(&self) -> Indexes<'_> {
846        Indexes {
847            framework: self.framework,
848            table: self.table,
849            iter: self.table.indexes.vec.iter(),
850        }
851    }
852
853    pub fn refer_fields(&self) -> Option<Summary<'a>> {
854        if let Some(summary) = &self.table.refer_fields {
855            Some(Summary {
856                framework: self.framework,
857                table: self.table,
858                summary,
859            })
860        } else {
861            None
862        }
863    }
864
865    pub fn refer_summary(&self) -> Option<Summary<'a>> {
866        if let Some(summary) = &self.table.refer_summary {
867            Some(Summary {
868                framework: self.framework,
869                table: self.table,
870                summary,
871            })
872        } else {
873            None
874        }
875    }
876
877    pub fn suggest(&self) -> Option<Suggest<'_>> {
878        match &self.table.suggest {
879            Some(inner::Suggest::Choice { choice }) =>
880                Some(Suggest::Choice {
881                    choice: DottedField::new(self.framework, self.table, choice),
882                }),
883
884            Some(inner::Suggest::IdentifierAndName { identifier, name }) =>
885                Some(Suggest::IdentifierAndName {
886                    identifier: DottedField::new(self.framework, self.table, identifier),
887                    name: DottedField::new(self.framework, self.table, name),
888                }),
889
890            Some(inner::Suggest::IdentifierAndNames { identifier, names }) =>
891                Some(Suggest::IdentifierAndNames {
892                    identifier: DottedField::new(self.framework, self.table, identifier),
893                    names: DottedField::new(self.framework, self.table, names),
894                }),
895
896            Some(inner::Suggest::Name { name }) =>
897                Some(Suggest::Name {
898                    name: DottedField::new(self.framework, self.table, name),
899                }),
900
901            Some(inner::Suggest::Names { names }) =>
902                Some(Suggest::Names {
903                    names: DottedField::new(self.framework, self.table, names),
904                }),
905
906            _ =>
907                None,
908        }
909    }
910
911    pub fn summary(&self) -> Option<Summary<'a>> {
912        if let Some(summary) = &self.table.summary {
913            Some(Summary {
914                framework: self.framework,
915                table: self.table,
916                summary,
917            })
918        } else {
919            None
920        }
921    }
922}
923
924pub struct Tables<'a> {
925    framework: &'a Framework,
926    iter: std::slice::Iter<'a, inner::Table>,
927}
928
929impl<'a> Iterator for Tables<'a> {
930    type Item = Table<'a>;
931
932    fn next(&mut self) -> Option<Self::Item> {
933        if let Some(table) = self.iter.next() {
934            Some(Table {
935                framework: self.framework,
936                table,
937            })
938        } else {
939            None
940        }
941    }
942}