Created
July 2, 2020 13:08
-
-
Save romanschejbal/fb9ccf352fe63ff4ac28531a735d5989 to your computer and use it in GitHub Desktop.
Tree thinning in Rust
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate xml; | |
use std::collections::HashMap; | |
use std::fs::File; | |
use std::io::BufReader; | |
use xml::reader::{EventReader, XmlEvent}; | |
// debugging helper ignore this | |
fn indent(size: usize) -> String { | |
const INDENT: &'static str = " "; | |
(0..size) | |
.map(|_| INDENT) | |
.fold(String::with_capacity(size * INDENT.len()), |r, s| r + s) | |
} | |
struct Node { | |
name: String, | |
value: Option<String>, | |
depth: u32, | |
children: HashMap<String, Self>, | |
} | |
impl Node { | |
fn new(name: String, depth: u32) -> Self { | |
Self { | |
name, | |
value: None, | |
depth, | |
children: HashMap::new(), | |
} | |
} | |
fn find_or_create_child(&mut self, name: String, depth: u32) -> &mut Self { | |
if !self.children.contains_key(&name) { | |
let node = Self::new(name.clone(), depth); | |
self.children.insert(name.clone(), node); | |
} | |
self.children.get_mut(&name).unwrap() | |
} | |
} | |
impl std::fmt::Debug for Node { | |
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | |
let debug = writeln!( | |
f, | |
"{}- {} ({:?})", | |
indent(self.depth as usize), | |
self.name, | |
self.value | |
); | |
if let Err(e) = debug { | |
panic!(e); | |
} | |
self.children.iter().for_each(|(_, child)| { | |
child.fmt(f).unwrap(); | |
}); | |
debug | |
} | |
} | |
fn parse(parser: &mut EventReader<BufReader<File>>, parent: &mut Node, depth: u32) { | |
while let Ok(event) = parser.next() { | |
match event { | |
XmlEvent::StartDocument { .. } => {} | |
XmlEvent::StartElement { name, .. } => { | |
let child = parent.find_or_create_child(name.local_name, depth + 1); | |
parse(parser, child, depth + 1); | |
} | |
XmlEvent::Characters(characters) => { | |
parent.value = Some(characters); | |
} | |
XmlEvent::EndDocument { .. } | XmlEvent::EndElement { .. } => break, | |
_ => {} | |
} | |
} | |
} | |
fn main() { | |
let file = File::open("zbozi.xml").unwrap(); | |
let file = BufReader::new(file); | |
let mut root = Node::new("ROOT".to_string(), 0); | |
let mut parser = EventReader::new(file); | |
let depth: u32 = 0; | |
parse(&mut parser, &mut root, depth); | |
println!("{:?}", root); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment