Browse Source

more examples

Johann Woelper 6 years ago
parent
commit
40c28fd7d5
3 changed files with 164 additions and 112 deletions
  1. 140 0
      src/example_xml.rs
  2. 0 0
      src/examples.rs
  3. 24 112
      src/main.rs

+ 140 - 0
src/example_xml.rs

@@ -0,0 +1,140 @@
+use std::ffi::OsStr;
+use std::fs::File;
+use std::io::BufReader;
+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
+
+pub fn xml() {
+    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
+    for f in WalkDir::new(&dir) {
+        let file = f.unwrap();
+        if file.path().is_file() {
+            let ext = file.path().extension().unwrap();
+            if ext == "xml" {
+                dbg!(ext);
+            }
+        }
+    }
+
+    // The safe way without unwrap()s
+    for file in WalkDir::new(&dir) {
+        match file {
+            Ok(valid_file) => {
+                match valid_file.path().extension() {
+                    Some(ext) => {
+                        if ext == "xml" {
+                            dbg!(valid_file);
+                            // do something here
+                        }
+                    }
+                    None => (),
+                }
+            }
+            Err(_e) => (),
+        }
+    }
+
+    // The functional way - produce a vec of valid files, then do something with it or pass it along
+    let xml_files: Vec<_> = WalkDir::new(&dir)
+        .into_iter() // creates an iterator
+        .filter_map(|e| e.ok()) // filters out invalid entries
+        .filter(|f| f.path().is_file()) // filters out directories
+        .filter(|f| f.path().extension() == Some(OsStr::new("xml"))) // leaves xml - a bit verbose
+        .collect();
+
+    dbg!(&xml_files);
+
+    for f in &xml_files {
+        dbg!(elements_from_xml(&f.path()));
+    }
+
+    // let a = xml_files.into_iter().map(|f| elements_from_xml_functional(f.path())).collect::<Vec<usize>>().sum();
+    let a: usize = xml_files
+        .into_iter()
+        .map(|f| elements_from_xml_functional(f.path()))
+        .sum();
+    dbg!(a);
+}
+
+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:
+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:
+fn elements_from_xml_functional(direntry: &Path) -> usize {
+    File::open(direntry)
+        .ok() //convert Result() to Option() so we don't get mismatched error types
+        .map(BufReader::new) //feed the open file into a BufReader
+        .and_then(|f| treexml::Document::parse(f).ok()) //parse it
+        .and_then(|r| r.root) //get the root element
+        .map(|r| {
+            r.children
+                .into_iter()
+                .filter(|e| e.name == "texture")
+                .collect::<Vec<_>>()
+                .len()
+        }) //iterate, filter and collect elements, then count them
+        .unwrap_or(0) //unwrap_or lets us specify a value that should be taken if unwrap fails
+}

+ 0 - 0
src/examples.rs


+ 24 - 112
src/main.rs

@@ -3,134 +3,46 @@
 // 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::fs::File;
-use std::io::BufReader;
+// use our xml module
+mod example_xml;
 
-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() {
-    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
-    for f in WalkDir::new(&dir) {
-        let file = f.unwrap();
-        if file.path().is_file() {
-            let ext = file.path().extension().unwrap();
-            if ext == "xml" {
-                dbg!(ext);
-            }
-        }
-    }
-
-    // The safe way without unwrap()s
-    for file in WalkDir::new(&dir) {
-        match file {
-            Ok(valid_file) => {
-                match valid_file.path().extension() {
-                    Some(ext) => {
-                        if ext == "xml" {
-                            dbg!(valid_file);
-                            // do something here
-                        }
-                    }
-                    None => (),
-                }
-            }
-            Err(_e) => (),
-        }
-    }
-
-    // The functional way - produce a vec of valid files, then do something with it or pass it along
-    let xml_files: Vec<_> = WalkDir::new(&dir)
-        .into_iter() // creates an iterator
-        .filter_map(|e| e.ok()) // filters out invalid entries
-        .filter(|f| f.path().is_file()) // filters out directories
-        .filter(|f| f.path().extension() == Some(OsStr::new("xml"))) // leaves xml - a bit verbose
-        .collect();
 
-    dbg!(&xml_files);
+// Functions "consume" vars
+fn say_hello(text: String) {
+    println!("hello {}", text);
+}
 
-    for f in xml_files {
-        dbg!(elements_from_xml(&f.path()));
-    }
 
 
+// Last line returns
+fn mult(val1: f32, val2: f32) -> f32 {
+    val1 * val2
 }
 
-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
+fn mult_oldschool(val1: f32, val2: f32) -> f32 {
+    let result = val1 * val2;
+    return result;
 }
 
-// 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 => (),
-    }
+// Every program starts with main()
+fn main() {
+
+    let name = String::from("Javier");
+    say_hello(name);
 
-    // 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;
-                    }
-                }
-            }
+    let test = Some("dsd");
+    match test {
+        Some(value) => {
+            1;
         }
+        None => (),
     }
-    counter
-}
 
+    example_xml::xml();
 
-// 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())
 
-}
+}