1use crate::error::Result;
8use crate::inventory::Inventory;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum Format {
13 Fdsn,
15 Sc3ml,
17}
18
19pub trait StationXmlFormat {
24 fn read_from_str(xml: &str) -> Result<Inventory>;
26
27 fn read_from_bytes(bytes: &[u8]) -> Result<Inventory>;
29
30 fn write_to_string(inventory: &Inventory) -> Result<String>;
32}
33
34pub fn detect_format(xml: &str) -> Option<Format> {
43 let mut reader = quick_xml::Reader::from_str(xml);
44 loop {
45 match reader.read_event() {
46 Ok(quick_xml::events::Event::Start(e)) => {
47 return match e.local_name().as_ref() {
48 b"FDSNStationXML" => Some(Format::Fdsn),
49 b"seiscomp" => Some(Format::Sc3ml),
50 _ => None,
51 };
52 }
53 Ok(quick_xml::events::Event::Eof) => return None,
54 Err(_) => return None,
55 _ => continue, }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn detect_fdsn_with_declaration() {
66 let xml = r#"<?xml version="1.0" encoding="UTF-8"?>
67<FDSNStationXML xmlns="http://www.fdsn.org/xml/station/1" schemaVersion="1.2">
68 <Source>Test</Source>
69</FDSNStationXML>"#;
70 assert_eq!(detect_format(xml), Some(Format::Fdsn));
71 }
72
73 #[test]
74 fn detect_fdsn_without_declaration() {
75 let xml = r#"<FDSNStationXML schemaVersion="1.2"><Source>T</Source></FDSNStationXML>"#;
76 assert_eq!(detect_format(xml), Some(Format::Fdsn));
77 }
78
79 #[test]
80 fn detect_sc3ml() {
81 let xml = r#"<?xml version="1.0"?>
82<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.13" version="0.13">
83 <Inventory></Inventory>
84</seiscomp>"#;
85 assert_eq!(detect_format(xml), Some(Format::Sc3ml));
86 }
87
88 #[test]
89 fn detect_with_comments() {
90 let xml = r#"<?xml version="1.0"?>
91<!-- This is a comment -->
92<FDSNStationXML schemaVersion="1.2"><Source>T</Source></FDSNStationXML>"#;
93 assert_eq!(detect_format(xml), Some(Format::Fdsn));
94 }
95
96 #[test]
97 fn detect_unknown() {
98 let xml = r#"<html><body>not station metadata</body></html>"#;
99 assert_eq!(detect_format(xml), None);
100 }
101
102 #[test]
103 fn detect_empty() {
104 assert_eq!(detect_format(""), None);
105 }
106
107 #[test]
108 fn detect_invalid_xml() {
109 assert_eq!(detect_format("not xml at all"), None);
110 }
111
112 #[test]
113 fn format_enum_copy() {
114 let f = Format::Fdsn;
115 let f2 = f; assert_eq!(f, f2);
117 }
118}