boring_parser/
parser.rs

1use crate::boring_structs_110::Boring110;
2use crate::error::ParseError;
3use quick_xml::Reader;
4use quick_xml::de::from_str;
5use quick_xml::events::Event;
6use quick_xml::se::to_string;
7use std::str::{self};
8
9pub trait Parse<T> {
10    fn parse_from_str(xml_str: &str) -> Result<T, Box<dyn std::error::Error>>;
11}
12
13impl Parse<Boring110> for Boring110 {
14    fn parse_from_str(xml_str: &str) -> Result<Boring110, Box<dyn std::error::Error>> {
15        let boring: Boring110 = from_str(xml_str)?;
16        Ok(boring)
17    }
18}
19
20pub trait ToXml {
21    fn to_xml_string(&self) -> Result<String, Box<dyn std::error::Error>>;
22}
23
24impl ToXml for Boring110 {
25    fn to_xml_string(&self) -> Result<String, Box<dyn std::error::Error>> {
26        let xml = to_string(&self)?;
27        Ok(xml)
28    }
29}
30
31pub fn extract_dtd_version(xml: &str) -> Result<String, ParseError> {
32    let mut reader = Reader::from_str(xml);
33    reader.trim_text(true);
34    let mut buf = Vec::new();
35    loop {
36        match reader.read_event_into(&mut buf) {
37            Ok(Event::Start(ref e)) if e.name().as_ref() == "ボーリング情報".as_bytes() => {
38                for attr in e.attributes().flatten() {
39                    if attr.key.as_ref() == b"DTD_version" {
40                        return Ok(attr.unescape_value().unwrap_or_default().to_string());
41                    }
42                }
43                break;
44            }
45            Ok(Event::Eof) => break,
46            _ => {}
47        }
48        buf.clear();
49    }
50    Err(ParseError::ParseError(String::from(
51        "DTD_version was not found. Plese check your XML file.",
52    )))
53}