1use crate::errors::{XmlReadError, XmlWriteError};
2use std::io::{Read, Write};
3use xml::{
4 attribute::OwnedAttribute,
5 name::OwnedName,
6 namespace::{Namespace, NS_NO_PREFIX},
7 reader::{self},
8 writer::{self, EventWriter, XmlEvent},
9 EventReader,
10};
11
12pub(crate) trait ToXml {
13 fn write_xml_element<W: Write>(&self, writer: &mut EventWriter<W>)
14 -> Result<(), XmlWriteError>;
15
16 fn will_write(&self) -> bool {
17 true
18 }
19}
20
21impl<T: ToXml> ToXml for Option<T> {
22 fn write_xml_element<W: Write>(
23 &self,
24 writer: &mut EventWriter<W>,
25 ) -> Result<(), XmlWriteError> {
26 if let Some(item) = self {
27 item.write_xml_element(writer)?;
28 }
29
30 Ok(())
31 }
32
33 fn will_write(&self) -> bool {
34 self.is_some()
35 }
36}
37
38pub(crate) trait ToInnerXml {
39 fn write_xml_named_element<W: Write>(
40 &self,
41 writer: &mut EventWriter<W>,
42 tag: &str,
43 ) -> Result<(), XmlWriteError>;
44
45 fn will_write(&self) -> bool {
46 true
47 }
48}
49
50impl<T: ToInnerXml> ToInnerXml for Option<T> {
51 fn write_xml_named_element<W: Write>(
52 &self,
53 writer: &mut EventWriter<W>,
54 tag: &str,
55 ) -> Result<(), XmlWriteError> {
56 if let Some(item) = self {
57 item.write_xml_named_element(writer, tag)?;
58 }
59
60 Ok(())
61 }
62
63 fn will_write(&self) -> bool {
64 self.is_some()
65 }
66}
67
68pub(crate) fn write_simple_tag<W: Write>(
70 writer: &mut EventWriter<W>,
71 tag: &str,
72 content: &str,
73) -> Result<(), XmlWriteError> {
74 writer
75 .write(writer::XmlEvent::start_element(tag))
76 .map_err(to_xml_write_error(tag))?;
77
78 writer
79 .write(writer::XmlEvent::characters(content))
80 .map_err(to_xml_write_error(tag))?;
81
82 writer
83 .write(writer::XmlEvent::end_element())
84 .map_err(to_xml_write_error(tag))?;
85 Ok(())
86}
87
88pub(crate) fn write_simple_option_tag<W: Write>(
89 writer: &mut EventWriter<W>,
90 tag: &str,
91 content: &Option<impl AsRef<str>>,
92) -> Result<(), XmlWriteError> {
93 if let Some(content) = content.as_ref() {
94 write_simple_tag(writer, tag, content.as_ref())?
95 }
96
97 Ok(())
98}
99
100pub(crate) fn write_start_tag<W: Write>(
102 writer: &mut EventWriter<W>,
103 tag: &str,
104) -> Result<(), XmlWriteError> {
105 writer
106 .write(XmlEvent::start_element(tag))
107 .map_err(to_xml_write_error(tag))
108}
109
110pub(crate) fn write_close_tag<W: Write>(
112 writer: &mut EventWriter<W>,
113 tag: &str,
114) -> Result<(), XmlWriteError> {
115 writer
116 .write(XmlEvent::end_element())
117 .map_err(to_xml_write_error(tag))
118}
119
120pub(crate) fn write_list_tag<W: Write>(
121 writer: &mut EventWriter<W>,
122 tag: &str,
123 list: &[impl ToXml],
124) -> Result<(), XmlWriteError> {
125 write_start_tag(writer, tag)?;
126
127 for item in list {
128 item.write_xml_element(writer)?;
129 }
130
131 write_close_tag(writer, tag)
132}
133
134pub(crate) fn write_list_string_tag<W: Write>(
135 writer: &mut EventWriter<W>,
136 tag: &str,
137 child_tag: &str,
138 list: &[impl AsRef<str>],
139) -> Result<(), XmlWriteError> {
140 write_start_tag(writer, tag)?;
141
142 for item in list {
143 write_simple_tag(writer, child_tag, item.as_ref())?;
144 }
145
146 write_close_tag(writer, tag)
147}
148
149pub(crate) fn to_xml_write_error(
150 element: impl AsRef<str>,
151) -> impl FnOnce(xml::writer::Error) -> XmlWriteError {
152 let element = element.as_ref().to_owned();
153 |error| XmlWriteError::XmlElementWriteError { error, element }
154}
155
156pub(crate) trait FromXmlDocument {
157 fn read_xml_document<R: Read>(event_reader: &mut EventReader<R>) -> Result<Self, XmlReadError>
158 where
159 Self: Sized;
160}
161
162pub(crate) trait FromXml {
163 fn read_xml_element<R: Read>(
164 event_reader: &mut EventReader<R>,
165 element_name: &OwnedName,
166 attributes: &[OwnedAttribute],
167 ) -> Result<Self, XmlReadError>
168 where
169 Self: Sized;
170}
171
172#[macro_export]
173macro_rules! get_elements_lax {
174 ($event_reader:ident, $element_name: ident, $($tag:pat => $name:ident: $type:ty,)+) => {
175 $(let mut $name: Option<$type> = None;)*
176
177 let mut got_end_tag = false;
178
179 while !got_end_tag {
180 let next_element = $event_reader.next().map_err($crate::xml::to_xml_read_error(&$element_name.local_name))?;
181 match next_element {
182 xml::reader::XmlEvent::StartElement {
183 name: ref elem_name,
184 ref attributes,
185 ..
186 } => {
187 match elem_name.local_name.as_str() {
188 $($tag => {
189 $name = Some(<$type as $crate::xml::FromXml>::read_xml_element(
190 $event_reader,
191 &elem_name,
192 &attributes,
193 )?);
194 },)*
195 _ => $crate::xml::read_lax_validation_tag($event_reader, &elem_name)?,
196 }
197 }
198 xml::reader::XmlEvent::EndElement { name } if &name == $element_name => {
199 got_end_tag = true;
200 }
201 unexpected => return Err($crate::xml::unexpected_element_error($element_name, unexpected)),
202 }
203 }
204 };
205}
206
207#[macro_export]
208macro_rules! get_elements {
209 ($event_reader:ident, $element_name: ident, $($tag:pat => $name:ident: $type:ty,)+) => {
210 $(let mut $name: Option<$type> = None;)*
211
212 let mut got_end_tag = false;
213
214 while !got_end_tag {
215 let next_element = $event_reader.next().map_err($crate::xml::to_xml_read_error(&$element_name.local_name))?;
216 match next_element {
217 xml::reader::XmlEvent::StartElement {
218 name: ref elem_name,
219 ref attributes,
220 ..
221 } => {
222 match elem_name.local_name.as_str() {
223 $($tag => {
224 $name = Some(<$type as $crate::xml::FromXml>::read_xml_element(
225 $event_reader,
226 &elem_name,
227 &attributes,
228 )?);
229 },)*
230 unexpected => return Err($crate::xml::unexpected_element_error(unexpected.to_string(), next_element)),
231 }
232 }
233 xml::reader::XmlEvent::EndElement { name } if &name == $element_name => {
234 got_end_tag = true;
235 }
236 unexpected => return Err($crate::xml::unexpected_element_error($element_name, unexpected)),
237 }
238 }
239 };
240}
241
242pub(crate) trait VecElemTag {
244 const VALUE: &'static str;
245}
246
247#[macro_export]
248macro_rules! elem_tag {
249 ($name:ident = $value:literal) => {
250 struct $name {}
251
252 impl $crate::xml::VecElemTag for $name {
253 const VALUE: &'static str = $value;
254 }
255 };
256}
257
258pub(crate) struct VecXmlReader<E: FromXml, T: VecElemTag> {
260 inner: Vec<E>,
261 _marker: std::marker::PhantomData<T>,
262}
263
264impl<E: FromXml, T: VecElemTag> From<VecXmlReader<E, T>> for Vec<E> {
265 fn from(reader: VecXmlReader<E, T>) -> Self {
266 reader.inner
267 }
268}
269
270impl<E: FromXml, T: VecElemTag> FromXml for VecXmlReader<E, T> {
271 fn read_xml_element<R: std::io::prelude::Read>(
272 event_reader: &mut xml::EventReader<R>,
273 element_name: &xml::name::OwnedName,
274 _attributes: &[xml::attribute::OwnedAttribute],
275 ) -> Result<Self, XmlReadError>
276 where
277 Self: Sized,
278 {
279 read_list_tag(event_reader, element_name, T::VALUE).map(|inner| Self {
280 inner,
281 _marker: Default::default(),
282 })
283 }
284}
285
286pub(crate) fn to_xml_read_error(
287 element_name: impl AsRef<str>,
288) -> impl FnOnce(xml::reader::Error) -> XmlReadError {
289 let element_name = element_name.as_ref().to_owned();
290 |error| XmlReadError::ElementReadError {
291 error,
292 element: element_name,
293 }
294}
295
296pub(crate) fn expected_namespace_or_error(
297 expected_version_number: impl AsRef<str>,
298 namespace: &Namespace,
299) -> Result<(), XmlReadError> {
300 let actual_namespace: Option<String> = namespace.get(NS_NO_PREFIX).map(String::from);
301 let expected_namespace = format!(
302 "http://cyclonedx.org/schema/bom/{}",
303 expected_version_number.as_ref()
304 );
305 if actual_namespace.as_ref() == Some(&expected_namespace) {
306 Ok(())
307 } else {
308 Err(XmlReadError::InvalidNamespaceError {
309 expected_namespace,
310 actual_namespace,
311 })
312 }
313}
314
315pub(crate) fn inner_text_or_error(
316 element_name: impl AsRef<str>,
317) -> impl FnOnce(xml::reader::XmlEvent) -> Result<String, XmlReadError> {
318 let element_name = element_name.as_ref().to_owned();
319 |event| match event {
320 reader::XmlEvent::Characters(s) | reader::XmlEvent::CData(s) => Ok(s),
321 unexpected => Err(unexpected_element_error(element_name, unexpected)),
322 }
323}
324
325pub(crate) fn inner_text_or_none(
326 element_name: impl AsRef<str>,
327) -> impl FnOnce(xml::reader::XmlEvent) -> Result<Option<String>, XmlReadError> {
328 let element_name = element_name.as_ref().to_owned();
329 |event| match event {
330 reader::XmlEvent::Characters(s) | reader::XmlEvent::CData(s) => Ok(Some(s)),
331 reader::XmlEvent::EndElement { name } if name.to_string() == element_name => Ok(None),
332 unexpected => Err(unexpected_element_error(element_name, unexpected)),
333 }
334}
335
336pub(crate) fn closing_tag_or_error(
337 element: &OwnedName,
338) -> impl FnOnce(xml::reader::XmlEvent) -> Result<(), XmlReadError> {
339 let element = element.clone();
340 move |event| match event {
341 reader::XmlEvent::EndElement { name } if name == element => Ok(()),
342 unexpected => Err(unexpected_element_error(&element, unexpected)),
343 }
344}
345
346pub(crate) fn attribute_or_error(
347 element_name: &OwnedName,
348 attributes: &[OwnedAttribute],
349 expected_attribute: &str,
350) -> Result<String, XmlReadError> {
351 attributes
352 .iter()
353 .filter(|attr| attr.name.local_name == expected_attribute)
354 .map(|attr| attr.value.to_owned())
355 .next()
356 .ok_or_else(|| XmlReadError::RequiredDataMissing {
357 required_field: expected_attribute.to_string(),
358 element: element_name.local_name.to_string(),
359 })
360}
361
362pub(crate) fn optional_attribute(
363 attributes: &[OwnedAttribute],
364 expected_attribute: &str,
365) -> Option<String> {
366 attributes
367 .iter()
368 .filter(|attr| attr.name.local_name == expected_attribute)
369 .map(|attr| attr.value.to_owned())
370 .next()
371}
372
373pub(crate) trait FromXmlType
374where
375 Self: Sized,
376{
377 fn xml_type_display() -> String;
378
379 fn from_xml_value(element: impl ToString, value: impl AsRef<str>)
380 -> Result<Self, XmlReadError>;
381}
382
383impl FromXmlType for bool {
384 fn xml_type_display() -> String {
385 "xs:boolean".to_string()
386 }
387
388 fn from_xml_value(
389 element: impl ToString,
390 value: impl AsRef<str>,
391 ) -> Result<Self, XmlReadError> {
392 let value = value.as_ref();
393 match value {
394 "true" | "1" => Ok(true),
395 "false" | "0" => Ok(false),
396 _ => Err(XmlReadError::InvalidParseError {
397 value: value.to_string(),
398 data_type: Self::xml_type_display(),
399 element: element.to_string(),
400 }),
401 }
402 }
403}
404
405impl FromXmlType for u32 {
406 fn xml_type_display() -> String {
407 "xs:integer".to_string()
408 }
409
410 fn from_xml_value(
411 element: impl ToString,
412 value: impl AsRef<str>,
413 ) -> Result<Self, XmlReadError> {
414 let value = value.as_ref();
415 let value: u32 = value.parse().map_err(|_| XmlReadError::InvalidParseError {
416 value: value.to_string(),
417 data_type: Self::xml_type_display(),
418 element: element.to_string(),
419 })?;
420
421 Ok(value)
422 }
423}
424
425impl FromXmlType for f32 {
426 fn xml_type_display() -> String {
427 "xs:decimal".to_string()
428 }
429
430 fn from_xml_value(
431 element: impl ToString,
432 value: impl AsRef<str>,
433 ) -> Result<Self, XmlReadError> {
434 let value = value.as_ref();
435 let value: f32 = value.parse().map_err(|_| XmlReadError::InvalidParseError {
436 value: value.to_string(),
437 data_type: Self::xml_type_display(),
438 element: element.to_string(),
439 })?;
440
441 Ok(value)
442 }
443}
444
445pub(crate) fn read_simple_tag<R: Read>(
457 event_reader: &mut EventReader<R>,
458 element: &OwnedName,
459) -> Result<String, XmlReadError> {
460 let element_display = element.to_string();
461 let content = event_reader
462 .next()
463 .map_err(to_xml_read_error(&element_display))?;
464
465 let content = match content {
466 reader::XmlEvent::EndElement { .. } => String::new(),
467 reader::XmlEvent::Characters(content) | reader::XmlEvent::CData(content) => {
468 event_reader
469 .next()
470 .map_err(to_xml_read_error(&element_display))
471 .and_then(closing_tag_or_error(element))?;
472 content
473 }
474 unexpected => return Err(unexpected_element_error(element, unexpected)),
475 };
476
477 Ok(content)
478}
479
480pub(crate) fn read_optional_tag<R: Read>(
481 event_reader: &mut EventReader<R>,
482 element: &OwnedName,
483) -> Result<Option<String>, XmlReadError> {
484 let element_display = element.to_string();
485 let content = event_reader
486 .next()
487 .map_err(to_xml_read_error(&element_display))
488 .and_then(inner_text_or_none(&element_display))?;
489
490 if content.is_some() {
492 event_reader
493 .next()
494 .map_err(to_xml_read_error(&element_display))
495 .and_then(closing_tag_or_error(element))?;
496 }
497
498 Ok(content)
499}
500
501pub(crate) fn read_u32_tag<R: Read>(
502 event_reader: &mut EventReader<R>,
503 element: &OwnedName,
504) -> Result<u32, XmlReadError> {
505 let element_display = element.to_string();
506 let content = event_reader
507 .next()
508 .map_err(to_xml_read_error(&element_display))
509 .and_then(inner_text_or_error(&element_display))?;
510
511 let number = match content.trim().parse::<u32>() {
512 Ok(n) => n,
513 Err(_) => {
514 return Err(XmlReadError::InvalidParseError {
515 value: content,
516 data_type: "u32".to_string(),
517 element: element_display,
518 })
519 }
520 };
521
522 event_reader
523 .next()
524 .map_err(to_xml_read_error(&element_display))
525 .and_then(closing_tag_or_error(element))?;
526
527 Ok(number)
528}
529
530pub(crate) fn read_f32_tag<R: Read>(
531 event_reader: &mut EventReader<R>,
532 element: &OwnedName,
533) -> Result<f32, XmlReadError> {
534 let element_display = element.to_string();
535 let content = event_reader
536 .next()
537 .map_err(to_xml_read_error(&element_display))
538 .and_then(inner_text_or_error(&element_display))?;
539
540 let number = match content.trim().parse::<f32>() {
541 Ok(n) => n,
542 Err(_) => {
543 return Err(XmlReadError::InvalidParseError {
544 value: content,
545 data_type: "f32".to_string(),
546 element: element_display,
547 })
548 }
549 };
550
551 event_reader
552 .next()
553 .map_err(to_xml_read_error(&element_display))
554 .and_then(closing_tag_or_error(element))?;
555
556 Ok(number)
557}
558
559pub(crate) fn read_boolean_tag<R: Read>(
560 event_reader: &mut EventReader<R>,
561 element: &OwnedName,
562) -> Result<bool, XmlReadError> {
563 read_simple_tag(event_reader, element)
564 .and_then(|modified| bool::from_xml_value(element, modified))
565}
566
567impl FromXml for String {
568 fn read_xml_element<R: Read>(
569 event_reader: &mut EventReader<R>,
570 element_name: &OwnedName,
571 _attributes: &[OwnedAttribute],
572 ) -> Result<Self, XmlReadError>
573 where
574 Self: Sized,
575 {
576 read_simple_tag(event_reader, element_name)
577 }
578}
579
580impl FromXml for u32 {
581 fn read_xml_element<R: Read>(
582 event_reader: &mut EventReader<R>,
583 element_name: &OwnedName,
584 _attributes: &[OwnedAttribute],
585 ) -> Result<Self, XmlReadError>
586 where
587 Self: Sized,
588 {
589 read_u32_tag(event_reader, element_name)
590 }
591}
592
593impl FromXml for f32 {
594 fn read_xml_element<R: Read>(
595 event_reader: &mut EventReader<R>,
596 element_name: &OwnedName,
597 _attributes: &[OwnedAttribute],
598 ) -> Result<Self, XmlReadError>
599 where
600 Self: Sized,
601 {
602 read_f32_tag(event_reader, element_name)
603 }
604}
605
606impl FromXml for bool {
607 fn read_xml_element<R: Read>(
608 event_reader: &mut EventReader<R>,
609 element_name: &OwnedName,
610 _attributes: &[OwnedAttribute],
611 ) -> Result<Self, XmlReadError>
612 where
613 Self: Sized,
614 {
615 read_boolean_tag(event_reader, element_name)
616 }
617}
618
619pub(crate) fn read_list_tag<R: Read, X: FromXml>(
620 event_reader: &mut EventReader<R>,
621 element_name: &OwnedName,
622 inner_element_tag: &str,
623) -> Result<Vec<X>, XmlReadError> {
624 let mut items = Vec::new();
625
626 let mut got_end_tag = false;
627 while !got_end_tag {
628 let next_element = event_reader
629 .next()
630 .map_err(to_xml_read_error(&element_name.local_name))?;
631 match next_element {
632 reader::XmlEvent::StartElement {
633 name, attributes, ..
634 } if name.local_name == inner_element_tag => {
635 items.push(X::read_xml_element(event_reader, &name, &attributes)?);
636 }
637 reader::XmlEvent::EndElement { name } if &name == element_name => {
638 got_end_tag = true;
639 }
640 unexpected => return Err(unexpected_element_error(element_name, unexpected)),
641 }
642 }
643
644 Ok(items)
645}
646
647pub(crate) fn read_lax_validation_tag<R: Read>(
648 event_reader: &mut EventReader<R>,
649 element: &OwnedName,
650) -> Result<(), XmlReadError> {
651 let mut got_end_tag = false;
652 while !got_end_tag {
653 let next_element = event_reader
654 .next()
655 .map_err(to_xml_read_error(&element.local_name))?;
656
657 match next_element {
658 reader::XmlEvent::StartElement { name, .. } => {
659 read_lax_validation_tag(event_reader, &name)?
660 }
661 reader::XmlEvent::EndElement { name } if &name == element => {
662 got_end_tag = true;
663 }
664 unexpected @ reader::XmlEvent::EndDocument => {
665 return Err(unexpected_element_error(element, unexpected))
666 }
667 unexpected @ reader::XmlEvent::EndElement { .. } => {
668 return Err(unexpected_element_error(element, unexpected))
669 }
670 _unknown => (),
671 }
672 }
673
674 Ok(())
675}
676
677pub(crate) fn read_lax_validation_list_tag<R: Read, X: FromXml>(
678 event_reader: &mut EventReader<R>,
679 element_name: &OwnedName,
680 inner_element_tag: &str,
681) -> Result<Vec<X>, XmlReadError> {
682 let mut items = Vec::new();
683
684 let mut got_end_tag = false;
685 while !got_end_tag {
686 let next_element = event_reader
687 .next()
688 .map_err(to_xml_read_error(&element_name.local_name))?;
689 match next_element {
690 reader::XmlEvent::StartElement {
691 name, attributes, ..
692 } if name.local_name == inner_element_tag => {
693 items.push(X::read_xml_element(event_reader, &name, &attributes)?);
694 }
695 reader::XmlEvent::StartElement { name, .. } => {
696 read_lax_validation_tag(event_reader, &name)?
697 }
698 reader::XmlEvent::EndElement { name } if &name == element_name => {
699 got_end_tag = true;
700 }
701 unexpected => return Err(unexpected_element_error(element_name, unexpected)),
702 }
703 }
704
705 Ok(items)
706}
707
708pub(crate) fn unexpected_element_error(
709 element: impl ToString,
710 unexpected: reader::XmlEvent,
711) -> XmlReadError {
712 XmlReadError::UnexpectedElementReadError {
713 error: format!("Got unexpected element {:?}", unexpected),
714 element: element.to_string(),
715 }
716}
717
718#[cfg(test)]
719pub(crate) mod test {
720 use xml::{EmitterConfig, ParserConfig};
721
722 use super::*;
723
724 fn emitter_config() -> EmitterConfig {
725 EmitterConfig::default().perform_indent(true)
726 }
727
728 pub(crate) fn write_element_to_string<X: ToXml>(element: X) -> String {
729 let mut output = Vec::new();
730 let mut event_writer = EventWriter::new_with_config(&mut output, emitter_config());
731 element
732 .write_xml_element(&mut event_writer)
733 .expect("Should have written the element");
734 String::from_utf8_lossy(&output).to_string()
735 }
736
737 pub(crate) fn write_named_element_to_string<X: ToInnerXml>(element: X, tag: &str) -> String {
738 let mut output = Vec::new();
739 let mut event_writer = EventWriter::new_with_config(&mut output, emitter_config());
740 element
741 .write_xml_named_element(&mut event_writer, tag)
742 .expect("Should have written the element");
743 String::from_utf8_lossy(&output).to_string()
744 }
745
746 fn parser_config() -> ParserConfig {
747 ParserConfig::default().trim_whitespace(true)
748 }
749
750 pub(crate) fn read_document_from_string<X: FromXmlDocument>(string: impl AsRef<str>) -> X {
751 let mut event_reader =
752 EventReader::new_with_config(string.as_ref().as_bytes(), parser_config());
753 let output: X = X::read_xml_document(&mut event_reader)
754 .expect("Failed to read the document from the string");
755
756 let end_document = event_reader.next().expect("Expected to end the document");
760
761 match end_document {
762 reader::XmlEvent::EndDocument { .. } => (),
763 other => panic!("Expected to end a document, but got {:?}", other),
764 }
765
766 output
767 }
768
769 pub(crate) fn read_element_from_string<X: FromXml>(string: impl AsRef<str>) -> X {
770 let mut event_reader =
771 EventReader::new_with_config(string.as_ref().as_bytes(), parser_config());
772
773 let start_document = event_reader.next().expect("Expected to start the document");
774
775 match start_document {
776 reader::XmlEvent::StartDocument { .. } => (),
777 other => panic!("Expected to start a document, but got {:?}", other),
778 }
779
780 let initial_event = event_reader
781 .next()
782 .expect("Failed to read from the XML input");
783 let output = match initial_event {
784 reader::XmlEvent::StartElement {
785 name, attributes, ..
786 } => X::read_xml_element(&mut event_reader, &name, &attributes)
787 .expect("Failed to read the element from the string"),
788 other => panic!("Expected to start an element, but got {:?}", other),
789 };
790 let end_document = event_reader.next().expect("Expected to end the document");
791
792 match end_document {
793 reader::XmlEvent::EndDocument { .. } => (),
794 other => panic!("Expected to end a document, but got {:?}", other),
795 }
796
797 output
798 }
799
800 #[test]
801 fn it_should_handle_invalid_lax_xml() {
802 let input = r#"
803<recursiveTag>
804 <innerTag>
805 <recursiveTag>
806 Text
807 </recursiveTag>
808 </innerTag>
809"#;
810 let mut event_reader = EventReader::new_with_config(input.as_bytes(), parser_config());
811
812 let start_document = event_reader.next().expect("Expected to start the document");
813
814 match start_document {
815 reader::XmlEvent::StartDocument { .. } => (),
816 other => panic!("Expected to start a document, but got {:?}", other),
817 }
818
819 let start_lax_element = event_reader.next().expect("Expected to start the document");
820
821 match start_lax_element {
822 reader::XmlEvent::StartElement { name, .. } => {
823 read_lax_validation_tag(&mut event_reader, &name)
824 .expect_err("Should have failed to parse invalid input");
825 }
826 other => panic!("Expected to start an element, but got {:?}", other),
827 }
828
829 }
831}