After reading the rust book, here's my first attempt to write rust. I decided to port one of my existing projects that I regularly use to rust, starting with one of the things it does: parse some data out of a structured xml file.
use roxmltree::Document;
use std::collections::HashSet;
#[derive(Debug)]
struct Meta {
title: Option<String>,
passwords: Option<HashSet<String>>, // Can appear multiple times
tags: Option<HashSet<String>>, // Can appear multiple times
category: Option<String>,
}
fn main() {
let xml_content = r#"
<abc>
<head>
<meta type="title">Title</meta>
<meta type="password">secret</meta>
<meta type="password">secret2</meta>
<meta type="tag">Tag</meta>
<meta type="category">Cat</meta>
</head>
</abc>
"#;
let doc = Document::parse(xml_content).expect("Failed to parse XML");
let mut title: Option<String> = None;
let mut passwords: HashSet<String> = HashSet::new();
let mut tags: HashSet<String> = HashSet::new();
let mut category: Option<String> = None;
for meta in doc.descendants().filter(|n| n.has_tag_name("meta")) {
if let Some("title") = meta.attribute("type") {
title = match meta.text() {
Some(text) => Some(text.to_string()),
None => None,
};
}
if let Some("category") = meta.attribute("type") {
category = match meta.text() {
Some(text) => Some(text.to_string()),
None => None,
};
}
if let Some("password") = meta.attribute("type") {
if let Some(text) = meta.text() {
passwords.insert(text.to_string());
}
}
if let Some("tag") = meta.attribute("type") {
if let Some(text) = meta.text() {
tags.insert(text.to_string());
}
}
}
let metadata = Meta {
title,
passwords: if passwords.is_empty() {
None
} else {
Some(passwords)
},
tags: if tags.is_empty() { None } else { Some(tags) },
category,
};
println!("{:?}", metadata);
// Meta { title: Some("Title"), passwords: Some({"secret2", "secret"}), tags: Some({"Tag"}), category: Some("Cat") }
}