diff --git a/Cargo.lock b/Cargo.lock index 189c64ea4..10a2d8490 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -463,6 +463,7 @@ version = "1.0.0-alpha.4" dependencies = [ "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index d5204145c..825081cd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ itertools = "0.8.0" image-meta = "0.1.0" quick-xml = "0.15.0" escaper = "0.1.0" +bitflags = "1.1.0" [dev-dependencies] tempfile = "3.0" diff --git a/src/location.rs b/src/location.rs index abfd4101f..08e641921 100644 --- a/src/location.rs +++ b/src/location.rs @@ -1,3 +1,4 @@ +use bitflags::bitflags; use quick_xml; use quick_xml::events::{BytesEnd, BytesStart, BytesText}; @@ -39,10 +40,22 @@ impl Location { pub struct Kml { pub addr: Option, pub locations: Option>, - pub tag: i32, + tag: KmlTag, pub curr: Location, } +bitflags! { + #[derive(Default)] + struct KmlTag: i32 { + const UNDEFINED = 0x00; + const PLACEMARK = 0x01; + const TIMESTAMP = 0x02; + const WHEN = 0x04; + const POINT = 0x08; + const COORDINATES = 0x10; + } +} + impl Kml { pub fn new() -> Self { Default::default() @@ -87,7 +100,7 @@ impl Kml { } fn text_cb(&mut self, event: &BytesText, reader: &quick_xml::Reader) { - if 0 != self.tag & (0x4 | 0x10) { + if self.tag.contains(KmlTag::WHEN) || self.tag.contains(KmlTag::COORDINATES) { let val = event.unescape_and_decode(reader).unwrap_or_default(); let val = val @@ -96,7 +109,7 @@ impl Kml { .replace("\t", "") .replace(" ", ""); - if 0 != self.tag & 0x4 && val.len() >= 19 { + if self.tag.contains(KmlTag::WHEN) && val.len() >= 19 { // YYYY-MM-DDTHH:MM:SSZ // 0 4 7 10 13 16 19 match chrono::NaiveDateTime::parse_from_str(&val, "%Y-%m-%dT%H:%M:%SZ") { @@ -110,7 +123,7 @@ impl Kml { self.curr.timestamp = time(); } } - } else if 0 != self.tag & 0x10 { + } else if self.tag.contains(KmlTag::COORDINATES) { let parts = val.splitn(2, ',').collect::>(); if parts.len() == 2 { self.curr.longitude = parts[0].parse().unwrap_or_default(); @@ -124,7 +137,7 @@ impl Kml { let tag = String::from_utf8_lossy(event.name()).trim().to_lowercase(); if tag == "placemark" { - if 0 != self.tag & 0x1 + if self.tag.contains(KmlTag::PLACEMARK) && 0 != self.curr.timestamp && 0. != self.curr.latitude && 0. != self.curr.longitude @@ -133,7 +146,7 @@ impl Kml { locations.push(std::mem::replace(&mut self.curr, Location::new())); } } - self.tag = 0 + self.tag = KmlTag::UNDEFINED; }; } @@ -152,19 +165,19 @@ impl Kml { self.addr = addr.unwrap().unescape_and_decode_value(reader).ok(); } } else if tag == "placemark" { - self.tag = 0x1; + self.tag = KmlTag::PLACEMARK; self.curr.timestamp = 0; self.curr.latitude = 0.0; self.curr.longitude = 0.0; self.curr.accuracy = 0.0 - } else if tag == "timestamp" && 0 != self.tag & 0x1 { - self.tag = 0x1 | 0x2 - } else if tag == "when" && 0 != self.tag & 0x2 { - self.tag = 0x1 | 0x2 | 0x4 - } else if tag == "point" && 0 != self.tag & 0x1 { - self.tag = 0x1 | 0x8 - } else if tag == "coordinates" && 0 != self.tag & 0x8 { - self.tag = 0x1 | 0x8 | 0x10; + } else if tag == "timestamp" && self.tag.contains(KmlTag::PLACEMARK) { + self.tag = KmlTag::PLACEMARK | KmlTag::TIMESTAMP + } else if tag == "when" && self.tag.contains(KmlTag::TIMESTAMP) { + self.tag = KmlTag::PLACEMARK | KmlTag::TIMESTAMP | KmlTag::WHEN + } else if tag == "point" && self.tag.contains(KmlTag::PLACEMARK) { + self.tag = KmlTag::PLACEMARK | KmlTag::POINT + } else if tag == "coordinates" && self.tag.contains(KmlTag::POINT) { + self.tag = KmlTag::PLACEMARK | KmlTag::POINT | KmlTag::COORDINATES; if let Some(acc) = event.attributes().find(|attr| { attr.as_ref() .map(|a| String::from_utf8_lossy(a.key).trim().to_lowercase() == "accuracy")