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}