Browse Source

Refactor and cmd line args

Johann Woelper 7 years ago
parent
commit
937fde137f
3 changed files with 239 additions and 123 deletions
  1. 89 0
      Cargo.lock
  2. 2 1
      Cargo.toml
  3. 148 122
      src/main.rs

+ 89 - 0
Cargo.lock

@@ -1,3 +1,21 @@
+[[package]]
+name = "ansi_term"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termion 1.5.1 (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"
 version = "0.3.9"
@@ -19,6 +37,11 @@ dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "bitflags"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "cc"
 version = "1.0.18"
@@ -39,6 +62,20 @@ dependencies = [
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "clap"
+version = "2.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "encoding_rs"
 version = "0.7.2"
@@ -97,6 +134,7 @@ name = "pothole"
 version = "0.1.1"
 dependencies = [
  "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quick-xml 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -120,11 +158,24 @@ name = "redox_syscall"
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "redox_termios"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "redox_syscall 0.1.40 (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 = "strsim"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "syn"
 version = "0.11.11"
@@ -152,6 +203,24 @@ dependencies = [
  "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "termion"
+version = "1.5.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)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "time"
 version = "0.1.40"
@@ -162,11 +231,21 @@ dependencies = [
  "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "unicode-width"
+version = "0.1.5"
+source = "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 = "vec_map"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "winapi"
 version = "0.3.5"
@@ -187,11 +266,15 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
+"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
 "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 bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
 "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 clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
 "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"
@@ -202,12 +285,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "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 redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
 "checksum rustc-demangle 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "76d7ba1feafada44f2d38eed812bd2489a03c0f5abb975799251518b68848649"
+"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
 "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 termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
+"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
 "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
+"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
+"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
 "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 <woelper@gmail.com>"]
 
 [dependencies]
 chrono = "0.4"
-quick-xml = "0.12.0"
+quick-xml = "0.12.0"
+clap = "2.0"

+ 148 - 122
src/main.rs

@@ -1,19 +1,21 @@
 extern crate chrono;
 extern crate quick_xml;
+extern crate clap;
 
-use std::time::Duration as stdDuration;
-use std::io::Cursor;
-use std::str;
-use std::io::prelude::*;
 use std::fs::File;
+use std::io::prelude::*;
+use std::io::Cursor;
 use std::path::Path;
+use std::str;
+use std::time::Duration as stdDuration;
 // use chrono::DateTime;
 use chrono::Duration;
 use chrono::TimeZone;
 use chrono::Utc;
-use quick_xml::events::{Event, BytesEnd, BytesStart};
+use quick_xml::events::{BytesEnd, BytesStart, Event};
 use quick_xml::Reader;
 use quick_xml::Writer;
+use clap::{Arg, App, SubCommand};
 
 #[derive(Debug, Clone)]
 struct Point {
@@ -56,54 +58,67 @@ impl Track {
     }
 
     fn to_xml(&self) {
-
         let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), 32, 4); //32 is space character
 
-
         let mut gpx_elem = BytesStart::owned(b"gpx".to_vec(), "gpx".len());
         gpx_elem.push_attribute(("creator", "Pothole"));
         assert!(writer.write_event(Event::Start(gpx_elem)).is_ok());
 
         let trk_elem = BytesStart::owned(b"trk".to_vec(), "trk".len());
-            assert!(writer.write_event(Event::Start(trk_elem)).is_ok());
+        assert!(writer.write_event(Event::Start(trk_elem)).is_ok());
 
-            let mut prev_point = &self.points[0];
+        let mut prev_point = &self.points[0];
 
-                let trkseg_elem = BytesStart::owned(b"trkseg".to_vec(), "trkseg".len());
-                assert!(writer.write_event(Event::Start(trkseg_elem)).is_ok());
+        let trkseg_elem = BytesStart::owned(b"trkseg".to_vec(), "trkseg".len());
+        assert!(writer.write_event(Event::Start(trkseg_elem)).is_ok());
 
-            for pt in &self.points {
-                //segment detection
-                let d = dist(prev_point, pt);
-                prev_point = pt;
+        for pt in &self.points {
+            //segment detection
+            let d = dist(prev_point, pt);
+            prev_point = pt;
 
-                if d > 0.5 {
-                assert!(writer.write_event(Event::End(BytesEnd::borrowed(b"trkseg"))).is_ok());
+            if d > 0.5 {
+                assert!(
+                    writer
+                        .write_event(Event::End(BytesEnd::borrowed(b"trkseg")))
+                        .is_ok()
+                );
                 let trkseg_elem = BytesStart::owned(b"trkseg".to_vec(), "trkseg".len());
                 assert!(writer.write_event(Event::Start(trkseg_elem)).is_ok());
-                } else {
-                    
-                }
-                
-                let mut pt_elem = BytesStart::owned(b"trkpt".to_vec(), "trkpt".len());
-                pt_elem.push_attribute(("lat", pt.lat.to_string().as_str()));
-                pt_elem.push_attribute(("lon", pt.long.to_string().as_str()));
-                pt_elem.push_attribute(("ele", pt.ele.to_string().as_str()));
-                assert!(writer.write_event(Event::Start(pt_elem)).is_ok());
-                assert!(writer.write_event(Event::End(BytesEnd::borrowed(b"trkpt"))).is_ok());
+            } else {
 
             }
 
+            let mut pt_elem = BytesStart::owned(b"trkpt".to_vec(), "trkpt".len());
+            pt_elem.push_attribute(("lat", pt.lat.to_string().as_str()));
+            pt_elem.push_attribute(("lon", pt.long.to_string().as_str()));
+            pt_elem.push_attribute(("ele", pt.ele.to_string().as_str()));
+            assert!(writer.write_event(Event::Start(pt_elem)).is_ok());
+            assert!(
+                writer
+                    .write_event(Event::End(BytesEnd::borrowed(b"trkpt")))
+                    .is_ok()
+            );
+        }
 
-            assert!(writer.write_event(Event::End(BytesEnd::borrowed(b"trk"))).is_ok());
-        assert!(writer.write_event(Event::End(BytesEnd::borrowed(b"gpx"))).is_ok());
-
+        assert!(
+            writer
+                .write_event(Event::End(BytesEnd::borrowed(b"trk")))
+                .is_ok()
+        );
+        assert!(
+            writer
+                .write_event(Event::End(BytesEnd::borrowed(b"gpx")))
+                .is_ok()
+        );
 
         let result = writer.into_inner().into_inner();
         // println!("{:?}", str::from_utf8( &result).unwrap());
 
-        write_bytes(result, "track.gpx".to_string());
-        
+
+        let mut name: String = self.name.clone();
+        name.push_str(".gpx");
+        write_bytes(result, name);
     }
 
     fn time(&self) -> chrono::Duration {
@@ -125,12 +140,11 @@ impl Track {
 
     fn truncate_by_length(&mut self, length_km: f64) {
         while self.len() > length_km {
-                self.points.remove(0);
+            self.points.remove(0);
         }
     }
 
     fn parse(&mut self) {
-
         // how far to average the track together
         let sample_distance = 0.1;
         // This is where a track is considered bad = min_speed_factor * your average over sample_distance
@@ -142,15 +156,16 @@ impl Track {
             ..Default::default()
         };
 
-        let mut analyzed_track = Track { name: "analyzed".to_string(),
+        let mut analyzed_track = Track {
+            name: "analyzed".to_string(),
             ..Default::default()
         };
-        
-        let mut bad_track = Track { name: "bad".to_string(),
+
+        let mut bad_track = Track {
+            name: "bad".to_string(),
             ..Default::default()
         };
 
-
         for pt in &self.points {
             // i = i + 1; if i > 30 {break};
             fifo_track.points.push(pt.clone());
@@ -164,6 +179,84 @@ impl Track {
         }
         bad_track.to_xml();
     }
+
+    fn from_xml(&mut self, filename: String) {
+        
+    
+
+        // Records for the pull parser
+        let mut current_point = Point::new();
+        let mut current_data = "".to_string();
+
+        println!("XML parse start.");
+
+        let mut reader = Reader::from_file(filename).unwrap();
+        reader.trim_text(true);
+        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 key = reader.decode(unwrapped_attr.key).into_owned();
+                                let value =
+                                    unwrapped_attr.unescape_and_decode_value(&reader).unwrap();
+
+                                match key.as_str() {
+                                    "lat" => current_point.lat = value.parse().unwrap(),
+                                    "lon" => current_point.long = value.parse().unwrap(),
+                                    "ele" => current_point.ele = value.parse().unwrap(),
+                                    _ => (),
+                                }
+                            }
+                            ()
+                        }
+                        _ => (),
+                    }
+                }
+                // current_data = text;
+                Ok(Event::Text(e)) => {
+                    current_data = e.unescape_and_decode(&reader).unwrap();
+                    // txt.push(e.unescape_and_decode(&reader).unwrap()),
+                }
+                Ok(Event::End(ref e)) => {
+                    match e.name() {
+                        b"ele" => {
+                            current_point.ele = current_data.parse().unwrap();
+                        }
+                        b"name" => {
+                            self.name = current_data.clone();
+                        }
+                        b"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),
+                            }
+                        }
+                        b"trkpt" => {
+                            // push a copy of the point to the track
+                            self.points.push(current_point.clone());
+                        }
+                        _ => (),
+                    }
+                }
+                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
+            }
+
+            // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
+            buf.clear();
+        }
+
+        println!("XML parse end.");
+    }
 }
 
 fn dist(p1: &Point, p2: &Point) -> f64 {
@@ -179,9 +272,7 @@ fn dist(p1: &Point, p2: &Point) -> f64 {
     return r * c;
 }
 
-
 fn write_bytes(bytes_to_write: Vec<u8>, filename: String) {
-
     let path = Path::new(filename.as_str());
     let display = path.display();
 
@@ -191,105 +282,40 @@ fn write_bytes(bytes_to_write: Vec<u8>, filename: String) {
         Ok(file) => file,
     };
 
-        // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>`
+    // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>`
     match file.write_all("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".as_bytes()) {
-        Err(why) => {
-            panic!("couldn't write to {}", display)
-        },
+        Err(_why) => panic!("couldn't write to {}", display),
         Ok(_) => (println!("Wrote header -> {}", display)),
     }
 
     match file.write_all(&bytes_to_write) {
-        Err(why) => {
-            panic!("couldn't write to {}", display)
-        },
+        Err(_why) => panic!("couldn't write to {}", display),
         Ok(_) => println!("Wrote data -> {}", display),
     }
 }
 
 fn main() {
 
-    let mut trk = Track {
-        ..Default::default()
-    };
 
-    // Records for the pull parser
-    let mut current_point = Point::new();
-    let mut current_data = "".to_string();
-
-    println!("XML parse start.");
-
-    let mut reader = Reader::from_file("data/Day1-1.gpx").unwrap();
-    reader.trim_text(true);
-    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 key = reader.decode(unwrapped_attr.key).into_owned();
-                            let value = unwrapped_attr.unescape_and_decode_value(&reader).unwrap();
-
-                            match key.as_str() {
-                                "lat" => current_point.lat = value.parse().unwrap(),
-                                "lon" => current_point.long = value.parse().unwrap(),
-                                "ele" => current_point.ele = value.parse().unwrap(),
-                                _ => ()
-                                }
-                        }
-                        ()
-                    }
-                    _ => (),
-                }
-            }
-            // current_data = text;
-            Ok(Event::Text(e)) => {
-                current_data = e.unescape_and_decode(&reader).unwrap();
-                // txt.push(e.unescape_and_decode(&reader).unwrap()),
-            }
-            Ok(Event::End(ref e)) => {
-
-
-                match e.name() {
-                    b"ele" => {
-                        current_point.ele = current_data.parse().unwrap();
-                    },
-                    b"name" => {
-                        trk.name = current_data.clone();
-                    },
-                    b"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),
-                        }
-                    },
-                    b"trkpt" => {
-                        // push a copy of the point to the track
-                        trk.points.push(current_point.clone());
-                    },
-                    _ => ()
-                }
+let matches = App::new("Pothole")
+                          .arg(Arg::with_name("track")
+                               .long("track")
+                               .required(true)
+                               .value_name("FILE")
+                               .help("GPX file to process")
+                               .takes_value(true))
+                          .get_matches();
 
+    // Gets a value for config if supplied by user, or defaults to "default.conf"
+    let trackfile = matches.value_of("track").unwrap_or("data/Day1-1.gpx");
 
 
+    let mut trk = Track {
+        ..Default::default()
+    };
 
-            }
-            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
-        }
-
-        // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
-        buf.clear();
-    }
+    trk.from_xml(trackfile.to_string());
 
-    println!("XML parse end.");
 
     println!("Track name: {:?}", trk.name);
     println!("Distance: {:?} km", trk.len());