Skip to main content

xsd_schema/parser/frames/
xsd11.rs

1// ============================================================================
2// Alternative Frame (XSD 1.1)
3// ============================================================================
4
5/// Frame for xs:alternative
6pub struct AlternativeFrame {
7    test: Option<String>,
8    type_ref: Option<TypeRefResult>,
9    inline_type: Option<Box<TypeFrameResult>>,
10    xpath_default_namespace: Option<String>,
11    ns_snapshot: NamespaceContextSnapshot,
12    id: Option<String>,
13    annotation: Option<Annotation>,
14    source: Option<SourceRef>,
15    foreign_attributes: Vec<ForeignAttribute>,
16}
17
18impl AlternativeFrame {
19    pub fn new(
20        attrs: &AttributeMap,
21        name_table: &NameTable,
22        source: Option<SourceRef>,
23        ns_snapshot: NamespaceContextSnapshot,
24    ) -> SchemaResult<Self> {
25        let test = attrs
26            .get_value_by_name(name_table, "test")
27            .map(String::from);
28
29        let type_ref = attrs
30            .get_value_by_name(name_table, "type")
31            .map(|s| parse_qname_ref(s, name_table, &ns_snapshot))
32            .transpose()?
33            .map(TypeRefResult::QName);
34
35        let xpath_default_namespace = attrs
36            .get_value_by_name(name_table, "xpathDefaultNamespace")
37            .map(String::from);
38
39        let id = attrs
40            .get_value_by_name(name_table, "id")
41            .map(String::from);
42
43        Ok(Self {
44            test,
45            type_ref,
46            inline_type: None,
47            xpath_default_namespace,
48            ns_snapshot,
49            id,
50            annotation: None,
51            source,
52            foreign_attributes: Vec::new(),
53        })
54    }
55}
56
57impl Frame for AlternativeFrame {
58    fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
59        matches!(
60            local_name,
61            xsd_names::ANNOTATION | xsd_names::SIMPLE_TYPE | xsd_names::COMPLEX_TYPE
62        )
63    }
64
65    fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
66        matches!(
67            local_name,
68            "test" | "type" | "xpathDefaultNamespace" | "id"
69        )
70    }
71
72    fn on_child_start(&mut self, _local_name: &str, _name_table: &NameTable) {}
73
74    fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
75        match child {
76            FrameResult::Annotation(ann) => {
77                self.annotation = Some(ann);
78            }
79            FrameResult::Type(t) => {
80                self.inline_type = Some(Box::new(t));
81            }
82            FrameResult::Skip => {}
83            _ => {}
84        }
85        Ok(())
86    }
87
88    fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
89        let annotation = merge_foreign_attributes(
90            self.annotation,
91            self.foreign_attributes,
92            self.source.clone(),
93        );
94        Ok(FrameResult::Alternative(AlternativeResult {
95            test: self.test,
96            type_ref: self.type_ref,
97            inline_type: self.inline_type,
98            xpath_default_namespace: self.xpath_default_namespace,
99            ns_snapshot: self.ns_snapshot,
100            resolved_type: None,
101            id: self.id,
102            annotation,
103            source: self.source,
104        }))
105    }
106
107    fn has_annotation(&self) -> bool {
108        self.annotation.is_some()
109    }
110
111    fn source(&self) -> Option<&SourceRef> {
112        self.source.as_ref()
113    }
114
115    fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
116        self.foreign_attributes = attrs;
117    }
118}
119
120// ============================================================================
121// Assert Frame (XSD 1.1)
122// ============================================================================
123
124/// Frame for xs:assert
125pub struct AssertFrame {
126    test: String,
127    xpath_default_namespace: Option<String>,
128    ns_snapshot: NamespaceContextSnapshot,
129    id: Option<String>,
130    annotation: Option<Annotation>,
131    source: Option<SourceRef>,
132    foreign_attributes: Vec<ForeignAttribute>,
133}
134
135impl AssertFrame {
136    pub fn new(
137        attrs: &AttributeMap,
138        name_table: &NameTable,
139        source: Option<SourceRef>,
140        ns_snapshot: NamespaceContextSnapshot,
141    ) -> SchemaResult<Self> {
142        let test = attrs
143            .get_value_by_name(name_table, "test")
144            .map(String::from)
145            .unwrap_or_default();
146
147        let xpath_default_namespace = attrs
148            .get_value_by_name(name_table, "xpathDefaultNamespace")
149            .map(String::from);
150
151        let id = attrs
152            .get_value_by_name(name_table, "id")
153            .map(String::from);
154
155        Ok(Self {
156            test,
157            xpath_default_namespace,
158            ns_snapshot,
159            id,
160            annotation: None,
161            source,
162            foreign_attributes: Vec::new(),
163        })
164    }
165}
166
167impl Frame for AssertFrame {
168    fn allows(&self, local_name: &str, _name_table: &NameTable) -> bool {
169        matches!(local_name, xsd_names::ANNOTATION)
170    }
171
172    fn allows_attribute(&self, local_name: &str, _name_table: &NameTable) -> bool {
173        matches!(local_name, "test" | "xpathDefaultNamespace" | "id")
174    }
175
176    fn on_child_start(&mut self, _local_name: &str, _name_table: &NameTable) {}
177
178    fn attach(&mut self, child: FrameResult) -> SchemaResult<()> {
179        if let FrameResult::Annotation(ann) = child {
180            self.annotation = Some(ann);
181        }
182        Ok(())
183    }
184
185    fn finish(self: Box<Self>) -> SchemaResult<FrameResult> {
186        let annotation = merge_foreign_attributes(
187            self.annotation,
188            self.foreign_attributes,
189            self.source.clone(),
190        );
191        Ok(FrameResult::Assert(AssertResult {
192            test: self.test,
193            xpath_default_namespace: self.xpath_default_namespace,
194            ns_snapshot: self.ns_snapshot,
195            id: self.id,
196            annotation,
197            source: self.source,
198        }))
199    }
200
201    fn has_annotation(&self) -> bool {
202        self.annotation.is_some()
203    }
204
205    fn source(&self) -> Option<&SourceRef> {
206        self.source.as_ref()
207    }
208
209    fn set_foreign_attributes(&mut self, attrs: Vec<ForeignAttribute>) {
210        self.foreign_attributes = attrs;
211    }
212}
213