Browse Source

WIP refactor to quick xml

Johann Woelper 7 years ago
parent
commit
7e74c7f10b
4 changed files with 326 additions and 78 deletions
  1. 134 0
      Cargo.lock
  2. 2 1
      Cargo.toml
  3. 8 0
      data/test.xml
  4. 182 77
      src/main.rs

+ 134 - 0
Cargo.lock

@@ -1,3 +1,34 @@
+[[package]]
+name = "backtrace"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "chrono"
 version = "0.4.4"
@@ -8,11 +39,46 @@ dependencies = [
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "encoding_rs"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "libc"
 version = "0.2.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "memchr"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "num-integer"
 version = "0.1.39"
@@ -31,14 +97,62 @@ name = "pothole"
 version = "0.1.0"
 dependencies = [
  "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "quick-xml"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "redox_syscall"
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "rustc-demangle"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "syn"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synom"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "time"
 version = "0.1.40"
@@ -49,6 +163,11 @@ dependencies = [
  "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "unicode-xid"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "winapi"
 version = "0.3.5"
@@ -74,12 +193,27 @@ version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
+"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
+"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275"
+"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
 "checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37"
+"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d"
+"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82"
+"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b"
 "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
+"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
 "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
 "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
+"checksum quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b14c27e04216596a49f2b82398a24f67ed9f131a5c0e0235496ea446bdacfb12"
+"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
+"checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
+"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd"
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
+"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

+ 2 - 1
Cargo.toml

@@ -5,4 +5,5 @@ authors = ["Johann Woelper <johann.woelper@king.com>"]
 
 [dependencies]
 xml-rs = "0.8"
-chrono = "0.4"
+chrono = "0.4"
+quick-xml = "0.12.0"

+ 8 - 0
data/test.xml

@@ -0,0 +1,8 @@
+<trkpt lat = "34.232323" lon = "23.2323232">
+    <tag2>
+        <!--Test comment-->Test inside tag2
+    </tag2>
+    <tag3>
+        Test 2
+    </tag3>
+</trkpt>

+ 182 - 77
src/main.rs

@@ -1,4 +1,5 @@
 extern crate chrono;
+extern crate quick_xml;
 extern crate xml;
 
 use chrono::DateTime;
@@ -9,6 +10,8 @@ use std::fs::File;
 use std::io::BufReader;
 use std::time::Duration as stdDuration;
 
+use quick_xml::events::Event;
+use quick_xml::Reader;
 use xml::reader::{EventReader, XmlEvent};
 
 #[derive(Debug, Clone)]
@@ -68,8 +71,7 @@ impl Track {
         self.len() / (self.time().num_seconds() as f64 / 3600.0)
     }
 
-
-    fn truncate_by_length(&mut self, length_km: f64){
+    fn truncate_by_length(&mut self, length_km: f64) {
         let mut sum = 0.0;
         let mut prev_point = &self.points[0];
 
@@ -87,13 +89,17 @@ impl Track {
         let mut prev_point = &self.points[0];
         let mut prev_time = &self.points[0].time;
 
-        let mut fifo_track = Track {..Default::default()};
+        let mut fifo_track = Track {
+            ..Default::default()
+        };
 
-        let mut i=0;
+        let mut i = 0;
 
         for pt in &self.points {
-            i = i+1;
-            if i > 10 {break;}
+            i = i + 1;
+            if i > 10 {
+                break;
+            }
             let timespan = prev_time.signed_duration_since(pt.time);
             sum_time = sum_time.checked_sub(&timespan).unwrap();
             prev_time = &pt.time;
@@ -103,17 +109,10 @@ impl Track {
 
             fifo_track.points.push(pt.clone());
             println!("fifo len {:?}", fifo_track.points.len());
-
         }
-
-
     }
 }
 
-
-
-
-
 fn dist(p1: &Point, p2: &Point) -> f64 {
     let r = 6371.0;
     // println!("analyzing p1 {:?} p2 {:?}", p1, p2);
@@ -130,16 +129,16 @@ fn dist(p1: &Point, p2: &Point) -> f64 {
 }
 
 fn main() {
-    let file = File::open("data/Day1-1.gpx").unwrap();
-    let file = BufReader::new(file);
+    // let file = File::open("data/Day1-1.gpx").unwrap();
+    // let file = BufReader::new(file);
 
-    let mut trk = Track {
-        ..Default::default()
-    };
+    // let mut trk = Track {
+    //     ..Default::default()
+    // };
 
-    println!("open {:?}", file);
-    let parser = EventReader::new(file);
-    println!("done.");
+    // println!("open {:?}", file);
+    // let parser = EventReader::new(file);
+    // println!("done.");
 
     // Records for the pull parser
     let mut current_point = Point::new();
@@ -147,68 +146,174 @@ fn main() {
 
     println!("XML parse start.");
 
-    for e in parser {
-        match e {
-            
-            Ok(XmlEvent::StartElement {
-                name, attributes, ..
-            }) => {
-                if name.local_name == "trkpt" {
-                    for attr in attributes {
-                        // println!("A\t{:?}={:?}", attr.name.local_name, attr.value);
-                        if attr.name.local_name == "lat" {
-                            current_point.lat = attr.value.parse().unwrap();
-                        }
-                        if attr.name.local_name == "lon" {
-                            current_point.long = attr.value.parse().unwrap();
+    // for e in parser {
+    //     match e {
+
+    //         Ok(XmlEvent::StartElement {
+    //             name, attributes, ..
+    //         }) => {
+    //             if name.local_name == "trkpt" {
+    //                 for attr in attributes {
+    //                     // println!("A\t{:?}={:?}", attr.name.local_name, attr.value);
+    //                     if attr.name.local_name == "lat" {
+    //                         current_point.lat = attr.value.parse().unwrap();
+    //                     }
+    //                     if attr.name.local_name == "lon" {
+    //                         current_point.long = attr.value.parse().unwrap();
+    //                     }
+    //                 }
+    //             }
+    //         }
+
+    //         Ok(XmlEvent::Characters(text)) => {
+    //             // This event is the text between tags, such as <foo>text</foo>
+    //             current_data = text;
+    //         }
+
+    //         Ok(XmlEvent::EndElement { name, .. }) => {
+    //             // Elevation
+    //             if name.local_name == "ele" {
+    //                 current_point.ele = current_data.parse().unwrap();
+    //             }
+
+    //             // Parse time
+    //             if name.local_name == "time" {
+    //                 match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
+    //                     Ok(time) => current_point.time = time,
+    //                     Err(err) => println!("=== TIME ERROR === {:?}", err),
+    //                 }
+    //             }
+
+    //             // The track name
+    //             if name.local_name == "name" {
+    //                 trk.name = current_data.clone();
+    //             }
+
+    //             //Track point end event
+    //             if name.local_name == "trkpt" {
+    //                 // push a copy of the point to the track
+    //                 trk.points.push(current_point.clone());
+    //             }
+    //         }
+    //         Err(e) => {
+    //             println!("Error: {}", e);
+    //             break;
+    //         }
+
+    //         _ => {}
+    //     }
+    // }
+
+    // for e in parser {
+    //     match e {
+
+    //         Ok(XmlEvent::StartElement {
+    //             name, attributes, ..
+    //         }) => {
+    //             if name.local_name == "trkpt" {
+    //                 for attr in attributes {
+    //                     // println!("A\t{:?}={:?}", attr.name.local_name, attr.value);
+    //                     if attr.name.local_name == "lat" {
+    //                         current_point.lat = attr.value.parse().unwrap();
+    //                     }
+    //                     if attr.name.local_name == "lon" {
+    //                         current_point.long = attr.value.parse().unwrap();
+    //                     }
+    //                 }
+    //             }
+    //         }
+
+    //         Ok(XmlEvent::Characters(text)) => {
+    //             // This event is the text between tags, such as <foo>text</foo>
+    //             current_data = text;
+    //         }
+
+    //         Ok(XmlEvent::EndElement { name, .. }) => {
+    //             // Elevation
+    //             if name.local_name == "ele" {
+    //                 current_point.ele = current_data.parse().unwrap();
+    //             }
+
+    //             // Parse time
+    //             if name.local_name == "time" {
+    //                 match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
+    //                     Ok(time) => current_point.time = time,
+    //                     Err(err) => println!("=== TIME ERROR === {:?}", err),
+    //                 }
+    //             }
+
+    //             // The track name
+    //             if name.local_name == "name" {
+    //                 trk.name = current_data.clone();
+    //             }
+
+    //             //Track point end event
+    //             if name.local_name == "trkpt" {
+    //                 // push a copy of the point to the track
+    //                 trk.points.push(current_point.clone());
+    //             }
+    //         }
+    //         Err(e) => {
+    //             println!("Error: {}", e);
+    //             break;
+    //         }
+
+    //         _ => {}
+    //     }
+    // }
+
+    let mut reader = Reader::from_file("data/Day1-1.gpx").unwrap();
+    // let mut reader = Reader::from_file("data/test.xml").unwrap();
+
+    reader.trim_text(true);
+
+    let mut count = 0;
+    let mut txt = Vec::new();
+    let mut buf = Vec::new();
+
+    // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
+    loop {
+        match reader.read_event(&mut buf) {
+            Ok(Event::Start(ref e)) => {
+                // println!("{:?}", e.unescape_and_decode(&reader).unwrap());
+
+                match e.name() {
+                    b"trkpt" => {
+                        for a in e.attributes() {
+                            let unwrapped_attr = a.unwrap();
+                            let k = reader.decode(unwrapped_attr.key);
+                            let v = unwrapped_attr.unescape_and_decode_value(&reader).unwrap();
+                            if k == "lat" {
+                                current_point.lat = v.parse().unwrap();
+                            }
+                            if k == "lon" {
+                                current_point.long = v.parse().unwrap();
+                            }
+                            // println!("{:?}: {:?}", k, v);
                         }
+                        ()
                     }
+                    _ => (),
                 }
             }
-
-            Ok(XmlEvent::Characters(text)) => {
-                // This event is the text between tags, such as <foo>text</foo>
-                current_data = text;
-            }
-
-            Ok(XmlEvent::EndElement { name, .. }) => {
-                // Elevation
-                if name.local_name == "ele" {
-                    current_point.ele = current_data.parse().unwrap();
-                }
-
-                // Parse time
-                if name.local_name == "time" {
-                    match Utc.datetime_from_str(current_data.as_str(), "%FT%H:%M:%S%.3fZ") {
-                        Ok(time) => current_point.time = time,
-                        Err(err) => println!("=== TIME ERROR === {:?}", err),
-                    }
-                }
-
-                // The track name
-                if name.local_name == "name" {
-                    trk.name = current_data.clone();
-                }
-
-                //Track point end event
-                if name.local_name == "trkpt" {
-                    // push a copy of the point to the track
-                    trk.points.push(current_point.clone());
-                }
-            }
-            Err(e) => {
-                println!("Error: {}", e);
-                break;
-            }
-        
-            _ => {}
+            Ok(Event::Text(e)) => txt.push(e.unescape_and_decode(&reader).unwrap()),
+            // Ok(Event::End(ref e)) => (),
+            Ok(Event::Eof) => break, // exits the loop when reaching end of file
+            Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
+            _ => (), // There are several other `Event`s we do not consider here
         }
+
+        // print!("{:?}\n", buf);
+        // print!("{:?}\n", txt);
+        // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
+        buf.clear();
     }
+
     println!("XML parse end.");
 
-    println!("Track name: {:?}", trk.name);
-    println!("Distance: {:?} km", trk.len());
-    println!("Duration: {:?} h", trk.time().num_minutes() as f32 / 60.0);
-    println!("Speed: {:?} Km/h", trk.speed());
-    trk.parse();
+    // println!("Track name: {:?}", trk.name);
+    // println!("Distance: {:?} km", trk.len());
+    // println!("Duration: {:?} h", trk.time().num_minutes() as f32 / 60.0);
+    // println!("Speed: {:?} Km/h", trk.speed());
+    // trk.parse();
 }