#![cfg(feature = "cc_lib_gen")]
use crate::method::Class;
use super::*;
use minidom::Element;
const NAMESPACE: &'static str = "http://www.cccbr.org.uk/methods/schemas/2007/05/methods";
pub fn parse_cc_lib(xml: &str) -> MethodLib {
let root: Element = xml.parse().unwrap();
let date = root.attr("date").expect("Attr 'date' not found in root.");
println!("File last modified on {}", date);
MethodLib {
method_map: read_methods(&root),
}
}
fn read_methods(root: &Element) -> LibraryMap {
let mut methods: LibraryMap = HashMap::new();
for method_set in root.children().filter(|e| e.name() == "methodSet") {
let properties = method_set
.get_child("properties", NAMESPACE)
.expect("Couldn't find `properties` element");
let (stage, full_class) = read_properties(properties);
let method_map = methods.entry(stage).or_insert_with(HashMap::new);
for method in method_set.children().filter(|e| e.name() == "method") {
let title = method
.get_child("title", NAMESPACE)
.expect("Couldn't find `title` element")
.text();
let name = method
.get_child("name", NAMESPACE)
.expect("Couldn't find `name` element")
.text();
let place_notation = method
.get_child("notation", NAMESPACE)
.expect("Couldn't find `notation` element")
.text();
method_map.insert(
title,
CompactMethod {
name,
full_class,
place_notation,
},
);
}
}
methods
}
fn read_properties(properties: &Element) -> (Stage, FullClass) {
let stage: Stage = properties
.get_child("stage", NAMESPACE)
.expect("Couldn't find `stage` element")
.text()
.parse::<usize>()
.expect("Stage wasn't a valid number")
.into();
let classification_elem = properties
.get_child("classification", NAMESPACE)
.expect("Couldn't find `classification` element");
let is_little = classification_elem.attr("little") == Some("true");
let is_differential = classification_elem.attr("differential") == Some("true");
let class = match classification_elem.text().as_str() {
"" => Class::Principle,
"Place" => Class::Place,
"Bob" => Class::Bob,
"Treble Bob" => Class::TrebleBob,
"Delight" => Class::Delight,
"Surprise" => Class::Surprise,
"Treble Place" => Class::TreblePlace,
"Alliance" => Class::Alliance,
"Hybrid" => Class::Hybrid,
x => panic!("Unknown classification {:?}", x),
};
let full_class = FullClass::new(false, is_little, is_differential, class);
(stage, full_class)
}