diff --git a/src/main.rs b/src/main.rs index d7eb83e..e1b11dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ mod oop; use std::{thread::{self, JoinHandle}, io::Write}; -use roxmltree::{self, Document, Node}; +use roxmltree; fn main() { let args: Vec = std::env::args().collect(); @@ -28,7 +28,8 @@ fn main() { match doc { Ok(doc_good) => { //output(parse(&doc_good)); - parse(&doc_good); + #[allow(unused_variables)] + let output:oop::Family = new_parse(&doc_good).unwrap(); }, Err(doc_bad) => { println!("{:?}", doc_bad); @@ -43,80 +44,158 @@ fn main() { handle.join().expect("Couldn't close thread."); } } - - - -fn parse(doc: &Document) -> oop::Family { - let mut family: Option = None; - let mut family_name: String; +fn new_parse(doc:&roxmltree::Document) -> Result{ + let mut wrapped_family:Option = None; let mut messages: oop::Messages = oop::Messages::new(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new()); - for child1 in doc.root_element().first_children() { - if child1.is_element() && child1.tag_name().name() == "FAMILY" { - for attr in child1.attributes() { - if attr.name() == "name" { - family_name = attr.value().to_string(); - family = Some(oop::Family::new(family_name, Vec::new(), Vec::new())); - } else { - panic!("No family name found in file. Failed to initialize data structure.") + if let Some(root) = doc.root_element().first_child(){ + match root.tag_name().name() { + "FAMILY" => { + if let Some(attribute) = root.attributes().filter(|attribute| attribute.name() == "name" ).next(){ + wrapped_family = Some(oop::Family::new(attribute.value().to_string(), Vec::new(), Vec::new())); } - } - if let Some(ref mut real_family) = family { - for child2 in child1.children() { - if child2.is_element() { - if child2.tag_name().name() == "SPECIES_KEY" { - for child3 in child2.children() { - if child3.is_element() && child3.tag_name().name() == "GENUS" { - for attr in child3.attributes() { - if attr.name() == "name" { - real_family.push_genus(oop::Genus::new(attr.value().to_string(), Vec::new())); - } - } - for child4 in child3.children() { - if child4.is_element() && child4.tag_name().name() == "SPECIES" { - real_family.get_genera().last_mut().unwrap().push_species(oop::Species::new(child4.attribute_node("name").unwrap().value().to_string(), child4.attribute_node("defaultvalue").unwrap().value().to_string(), Vec::new())); - } - } - } - } - } else if child2.tag_name().name() == "DEFINITION" { - push_object(child2, real_family); - for child3 in child2.children() { - if child3.is_element() { - if child3.tag_name().name() == "MEMBERS" { - for child4 in child3.children() { - if child4.is_element() && child4.tag_name().name() == "MEMBER"{ - push_member(child2, child4, real_family); - } - } - } else if child3.tag_name().name() == "ENUMERATION" { - for child4 in child3.children() { - if child4.is_element() && child4.tag_name().name() == "ENUM"{ - push_enum(child2, child3, child4, real_family); - } - } - } - } - } - } else if child2.tag_name().name() == "MESSAGES" { - for child3 in child2.children() { - if child3.is_element() && child3.tag_name().name() == "MSG" { - messages.push(child3); - } - } - } - } - } - } + }, + _ => {} + } + + if let Some(ref mut family) = wrapped_family{ + root.children().for_each(|child| nested_parse(family, child)); + } + root.children().filter(|outer_child| outer_child.tag_name().name() == "MESSAGES" ) + .for_each(|message_group| { + message_group.children().filter(|inner_child| inner_child.tag_name().name() == "MSG") + .for_each(|message| { + messages.push(message); + }); + }); + + if let Some(family) = wrapped_family{ + return Ok(family); } } + return Err(core::fmt::Error); +} - if let Some(ref mut real_family) = family { - real_family.push_messages(messages); - println!("{:?}",real_family); - return family.unwrap(); - } else { - panic!("Family is uninitialized.") +fn nested_parse(input_family:&mut oop::Family, node: roxmltree::Node) { + match node.tag_name().name() { + "SPECIES_KEY" => { + node.children().for_each(|child| nested_parse(input_family, child)); + }, + "GENUS" => { + node.attributes() + .filter(|attr| attr.name() != "comment") + .for_each(|attr| { + if attr.name() == "name" { + input_family.push_genus(oop::Genus::new(attr.value().to_string(), Vec::new())); + }; + }); + node.children().for_each(|child| nested_parse(input_family, child)); + }, + "SPECIES" => { + input_family.get_genera().last_mut().unwrap() + .push_species(oop::Species::new( + node.attribute("name").unwrap().to_string(), + node.attribute("defaultvalue").unwrap().to_string(), + Vec::new() + )); + }, + "DEFINITION" => { + let Some(attr_family) = node.attribute("family") + else { todo!() }; + let Some(attr_genus) = node.attribute("genus") + else { todo!() }; + let Some(attr_species) = node.attribute("species") + else { todo!() }; + if attr_family != input_family.get_name() { + println!("Inconsistent family naming scheme. Check XML file."); + panic!(); + } + input_family.get_genera().as_mut_slice().iter_mut().filter(|genus| genus.get_name().as_str() == attr_genus) + .for_each(|genus| { + genus.get_species().as_mut_slice().iter_mut().filter(|species| species.get_name().as_str() == attr_species) + .for_each(|species|{ + species.push_object(oop::Object::new( + node.attribute("class").unwrap().to_string(), + node.attribute("abrv").unwrap().to_string(), + node.attribute("version").unwrap().to_string(), + Vec::new() + )); + }); + } + ); + node.children().for_each(|child| nested_parse(input_family, child)); + }, + "MEMBERS" => { + node.children().for_each(|child| nested_parse(input_family, child)); + }, + "MEMBER" => { + let Some(attr_family) = node.attribute("family") + else { todo!() }; + let Some(attr_genus) = node.attribute("genus") + else { todo!() }; + let Some(attr_species) = node.attribute("species") + else { todo!() }; + if attr_family != input_family.get_name() { + println!("Inconsistent family naming scheme. Check XML file."); + panic!(); + } + input_family.get_genera().as_mut_slice().iter_mut().filter(|genus| genus.get_name().as_str() == attr_genus) + .for_each(|genus| { + genus.get_species().as_mut_slice().iter_mut().filter(|species| species.get_name().as_str() == attr_species) + .for_each(|species|{ + species.get_objects().as_mut_slice().iter_mut() + .for_each(|object| { + object.push_object_member(oop::ObjectMember::new( + node.attribute("type").unwrap().to_string(), + node.attribute("name").unwrap().to_string(), + node.attribute("minversion").unwrap().to_string(), + node.attribute("maxversion").unwrap().to_string(), + Vec::new(), + node.attribute("format").unwrap_or("").to_string() + )); + }); + }); + } + ); + }, + "ENUMERATION" => { + node.children().for_each(|child| nested_parse(input_family, child)); + }, + "ENUM" => { + let Some(attr_family) = node.attribute("family") + else { todo!() }; + let Some(attr_genus) = node.attribute("genus") + else { todo!() }; + let Some(attr_species) = node.attribute("species") + else { todo!() }; + let Some(attr_name) = node.attribute("name") + else { todo!() }; + if attr_family != input_family.get_name() { + println!("Inconsistent family naming scheme. Check XML file."); + } + input_family.get_genera().as_mut_slice().iter_mut().filter(|genus| genus.get_name().as_str() == attr_genus) + .for_each(|genus| { + genus.get_species().as_mut_slice().iter_mut().filter(|species| species.get_name().as_str() == attr_species) + .for_each(|species|{ + species.get_objects().as_mut_slice().iter_mut() + .for_each(|object| { + object.get_members().as_mut_slice().iter_mut().filter(|member| member.get_name().as_str() == attr_name) + .for_each(|member| { + member.get_enumerations().push( + oop::MemberEnumeration::new( + node.attribute("name").unwrap().to_string(), + node.attribute("defaultvalue").unwrap_or("").to_string(), + ) + ); + }); + }); + }); + } + ); + }, + "MESSAGES" => {}, + "MSG" => {}, + _ => {} } } @@ -159,91 +238,3 @@ fn output(family: oop::Family) { } } -fn push_object(child2: Node, real_family: &mut oop::Family) { - if let Some(f) = child2.attribute_node("family") { - if f.value() ==real_family.get_name() { - for genus in real_family.get_genera().as_mut_slice() { - if let Some(g) = child2.attribute_node("genus") { - if g.value() == genus.get_name() { - for species in genus.get_species().as_mut_slice() { - if let Some(s) = child2.attribute_node("species") { - if s.value() == species.get_name() { - species.push_object(oop::Object::new(child2.attribute_node("class").unwrap().value().to_string(), child2.attribute_node("abrv").unwrap().value().to_string(), child2.attribute_node("version").unwrap().value().to_string(), Vec::new())) - } - } - } - } - } - } - } - } -} - -fn push_member(child2: Node, child4: Node, real_family: &mut oop::Family) { - if let Some(s) = child2.attribute_node("family") { - if s.value() ==real_family.get_name() { - for genus in real_family.get_genera().as_mut_slice() { - if let Some(g) = child2.attribute_node("genus") { - if g.value() == genus.get_name() { - for species in genus.get_species().as_mut_slice() { - if let Some(s) = child2.attribute_node("species") { - if s.value() == species.get_name() { - for object in species.get_objects().as_mut_slice() { - object.push_object_member(oop::ObjectMember::new( - child4.attribute_node("type").unwrap().value().to_string(), - child4.attribute_node("name").unwrap().value().to_string(), - child4.attribute_node("minversion").unwrap().value().to_string(), - child4.attribute_node("maxversion").unwrap().value().to_string(), - Vec::new(), - if child4.has_attribute("format") { - child4.attribute_node("format").unwrap().value().to_string() - } else { - String::new() - })); - - } - } - } - } - } - } - } - } - } -} - -fn push_enum(child2: Node, child3: Node, child4: Node, real_family: &mut oop::Family) { - if let Some(f) = child2.attribute_node("family") { - if f.value() ==real_family.get_name() { - for genus in real_family.get_genera().as_mut_slice() { - if let Some(g) = child2.attribute_node("genus") { - if g.value() == genus.get_name() { - for species in genus.get_species().as_mut_slice() { - if let Some(s) = child2.attribute_node("species") { - if s.value() == species.get_name() { - for object in species.get_objects().as_mut_slice() { - for member in object.get_members().as_mut_slice() { - if let Some(m) = child3.attribute_node("name") { - if m.value() == member.get_name() { - if child4.has_attribute("defaultvalue") { - member.get_enumerations().push(oop::MemberEnumeration::new( - child4.attribute_node("name").unwrap().value().to_string(), - child4.attribute_node("defaultvalue").unwrap().value().to_string())); - } else { - member.get_enumerations().push(oop::MemberEnumeration::new( - child4.attribute_node("name").unwrap().value().to_string(), - String::new())); - } - } - } - } - } - } - } - } - } - } - } - } - } -}