Browse Source

more examples

Johann Woelper 6 years ago
parent
commit
fba8562341
3 changed files with 236 additions and 9 deletions
  1. 140 0
      Cargo.lock
  2. 2 1
      Cargo.toml
  3. 94 8
      src/main.rs

+ 140 - 0
Cargo.lock

@@ -1,10 +1,94 @@
+[[package]]
+name = "autocfg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "backtrace"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "failure"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "iterfolder"
 version = "0.1.0"
 dependencies = [
+ "treexml 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "libc"
+version = "0.2.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "0.6.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "same-file"
 version = "1.0.4"
@@ -13,6 +97,41 @@ dependencies = [
  "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "syn"
+version = "0.15.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "treexml"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "failure 0.1.5 (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 = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "walkdir"
 version = "2.2.7"
@@ -50,10 +169,31 @@ name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "xml-rs"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [metadata]
+"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799"
+"checksum backtrace 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b493b66e03090ebc4343eb02f94ff944e0cbc9ac6571491d170ba026741eb5"
+"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6"
+"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e"
+"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
+"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
+"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
+"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"
+"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915"
+"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1"
+"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619"
 "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
+"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9"
+"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
+"checksum treexml 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "61b58a77e81f51d427f9cc3a5966211e5be59e5f3c4bfc395babf536595a7609"
+"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1"
 "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"

+ 2 - 1
Cargo.toml

@@ -5,4 +5,5 @@ authors = ["Johann Woelper <woelper@gmail.com>"]
 edition = "2018"
 
 [dependencies]
-walkdir = "*"
+walkdir = "*"
+treexml = "*"

+ 94 - 8
src/main.rs

@@ -1,15 +1,23 @@
 #![feature(dbg_macro)]
+#![allow(dead_code)]
+// TASK: count all occurrences of <texture> tags in all xml files
+// This will incrementally build the functionality so a lot is duplicated :)
+
 use std::ffi::OsStr;
-use std::path::PathBuf;
-use walkdir::WalkDir; //an external lib for traversing dirs //easy path manipulations like os.path on python
+use std::fs::File;
+use std::io::BufReader;
 
-// task: count all occurrences of <texture> tags in all xml files
+use std::path::Path;
+use treexml;
+use walkdir::WalkDir; //an external lib for traversing dirs //easy path manipulations like os.path on python // an external crate for XML-related tasks like etree / elementtree
 
+// Every program starts with main()
 fn main() {
-    // cheap one way to do it
-    let dir = "test";
+    let dir = "test"; // define our start dir here. Usually this would be a parameter passed to the program.
+
+    // Let's look at how we can iterate a folder:
 
-    // The dirty python way
+    // The dirty "python" way
     for f in WalkDir::new(&dir) {
         let file = f.unwrap();
         if file.path().is_file() {
@@ -20,7 +28,7 @@ fn main() {
         }
     }
 
-    // The python + rust safe way
+    // The safe way without unwrap()s
     for file in WalkDir::new(&dir) {
         match file {
             Ok(valid_file) => {
@@ -46,5 +54,83 @@ fn main() {
         .filter(|f| f.path().extension() == Some(OsStr::new("xml"))) // leaves xml - a bit verbose
         .collect();
 
-    dbg!(xml_files);
+    dbg!(&xml_files);
+
+    for f in xml_files {
+        dbg!(elements_from_xml(&f.path()));
+    }
+
+
+}
+
+pub fn elements_from_xml(direntry: &Path) -> u32 {
+    let mut counter = 0;
+    match File::open(direntry) {
+        Ok(f) => {
+            let buf_reader = BufReader::new(&f);
+            match treexml::Document::parse(buf_reader) {
+                Ok(doc) => match doc.root {
+                    Some(root) => {
+                        for child in root.children {
+                            if child.name == "texture" {
+                                counter += 1;
+                            }
+                        }
+                    }
+                    None => (),
+                },
+                Err(_e) => (),
+            }
+        }
+        Err(_e) => (),
+    }
+    counter
+}
+
+// The whole match thing is cool and all, but a bit long. Enter if let:
+
+fn let_test() {
+    let value = Some("str"); // value is either Some(v) or None.
+
+    // normal way:
+    match value {
+        Some(v) => {
+            dbg!(v);
+        }
+        None => (),
+    }
+
+    // This is better:
+    if let Some(v) = value {
+        dbg!(v);
+    }
+}
+
+// Now let us refactor the XML parser with if let:
+pub fn elements_from_xml_short(direntry: &Path) -> u32 {
+    let mut counter = 0;
+    if let Ok(f) = File::open(direntry) {
+        let buf_reader = BufReader::new(&f);
+        if let Ok(doc) = treexml::Document::parse(buf_reader) {
+            if let Some(root) = doc.root {
+                for child in root.children {
+                    if child.name == "texture" {
+                        counter += 1;
+                    }
+                }
+            }
+        }
+    }
+    counter
 }
+
+
+// A functional approach:
+pub fn elements_from_xml_functional(direntry: &Path) -> Option<usize> {
+    File::open(direntry)
+            .ok().map(|f| BufReader::new(f))
+            .and_then(|f| treexml::Document::parse(f).ok() )
+            .and_then(|r| r.root)
+            .map(|r| r.children.into_iter().filter(|e| e.name == "texture").collect::<Vec<_>>().len())
+
+}