111 lines
3.5 KiB
Rust
111 lines
3.5 KiB
Rust
use std::path::PathBuf;
|
|
use crate::config_reader::Directory;
|
|
|
|
use super::{Configuration, ErrorString, File};
|
|
|
|
pub fn parse(xml: String) -> Result<Configuration, Error> {
|
|
let mut config = Configuration::new();
|
|
let parser = roxmltree::Document::parse(xml.as_str())?;
|
|
let children = parser.root().children();
|
|
|
|
for node in children {
|
|
if node.is_element() && node.tag_name().name() == "ISO_Project" {
|
|
parse_iso_project(node, &mut config)?;
|
|
}
|
|
}
|
|
|
|
Ok(config)
|
|
}
|
|
|
|
fn parse_iso_project(iso_project: roxmltree::Node, config: &mut Configuration) -> Result<(), Error> {
|
|
for node in iso_project.children() {
|
|
if node.is_element() {
|
|
match node.tag_name().name() {
|
|
"Description" => parse_description(node, config),
|
|
"Track" => parse_track(node, config)?,
|
|
_ => ()
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn parse_description(description: roxmltree::Node, config: &mut Configuration) {
|
|
for node in description.descendants() {
|
|
if node.is_element() {
|
|
match node.tag_name().name() {
|
|
"Publisher" => config.publisher = Some(String::from(node.text().unwrap_or_default())),
|
|
"License" => config.license_path = Some(PathBuf::from(node.text().unwrap_or_default())),
|
|
_ => ()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn parse_track(track: roxmltree::Node, config: &mut Configuration) -> Result<(), Error> {
|
|
fn parse_file(file: roxmltree::Node) -> Result<File, Error> {
|
|
Ok(File{
|
|
name: String::from(file.attribute("name").unwrap_or_default()),
|
|
path: PathBuf::from(file.text().unwrap_or_default()),
|
|
is_hidden: parse_boolean_attribute(&file, "hidden")?
|
|
})
|
|
}
|
|
|
|
fn parse_file_system(cur_node: roxmltree::Node, root: &mut Directory) -> Result<(), Error> {
|
|
for node in cur_node.children() {
|
|
if node.is_element() {
|
|
match node.tag_name().name() {
|
|
"File" => root.add_file(parse_file(node)?),
|
|
"Directory" => {
|
|
let mut new_dir = Directory::new(node.attribute("name").unwrap_or_default());
|
|
|
|
parse_file_system(node, &mut new_dir)?;
|
|
root.add_dir(new_dir);
|
|
},
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
parse_file_system(track, &mut config.root)
|
|
}
|
|
|
|
fn parse_boolean_attribute(xml: &roxmltree::Node, attribute_name: &str) -> Result<bool, Error> {
|
|
if let Some(bool_str) = xml.attribute(attribute_name) {
|
|
match bool_str {
|
|
"true" | "1" => Ok(true),
|
|
"false" | "0" => Ok(false),
|
|
_ => {
|
|
return Err(Error::Generic(super::Error::from_text(format!("Attribute \"{}\" expects either true,false or 1,0 as valid attributes - found {}", attribute_name, bool_str))));
|
|
}
|
|
}
|
|
}
|
|
|
|
else {
|
|
Ok(false)
|
|
}
|
|
}
|
|
|
|
pub enum Error {
|
|
XML(roxmltree::Error),
|
|
Generic(super::Error)
|
|
}
|
|
|
|
impl ErrorString for Error {
|
|
fn to_string(self) -> String {
|
|
match self {
|
|
Self::XML(xml) => xml.to_string(),
|
|
Self::Generic(generic) => generic.to_string()
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::convert::From<roxmltree::Error> for Error {
|
|
fn from(error: roxmltree::Error) -> Error {
|
|
Error::XML(error)
|
|
}
|
|
} |