From 3f773a514e8a773be3c00610223faf0cc1159e7c Mon Sep 17 00:00:00 2001 From: Blizzard Finnegan Date: Tue, 8 Aug 2023 11:19:58 -0400 Subject: [PATCH] Make parse more readable --- src/main.rs | 371 +++++++++++++++++++++------------------------------- 1 file changed, 150 insertions(+), 221 deletions(-) diff --git a/src/main.rs b/src/main.rs index fe1d945..c79311a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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,231 +44,159 @@ 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:&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()); - if doc.root_element().has_children() { - for child1 in doc.root_element().first_children() { - if child1.is_element() { - print!("\n{:?}: ", child1.tag_name()); - if child1.tag_name().name().to_string().as_str() == "FAMILY" { - for attr in child1.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()); - if attr.name() == "name" { - family_name = attr.value().to_string(); - family = Some(oop::Family::new(family_name, Vec::new(), Vec::new())); - } - else { - panic!("Noreal_family name found. Failed to initialize data structure.") - } - } - } - if let Some(ref mut real_family) = family{ - if child1.has_children() { - for child2 in child1.children() { - if child2.is_element() { - print!("\n {:?}: ", child2.tag_name()); - if child2.tag_name().name().to_string().as_str() == "SPECIES_KEY" { - for attr in child2.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child2.has_children() { - for child3 in child2.children() { - if child3.is_element() { - print!("\n {:?}: ", child3.tag_name()); - if child3.tag_name().name().to_string().as_str() == "GENUS" { - for attr in child3.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()); - if attr.name() == "name" { - real_family.push_genus(oop::Genus::new(attr.value().to_string(), Vec::new())); - } - } - } - if child3.has_children() { - for child4 in child3.children() { - if child4.is_element() { - print!("\n {:?}: {:?}={:?} {:?}={:?}", child4.tag_name(), child4.attribute_node("name").unwrap().name().to_string(), child4.attribute_node("name").unwrap().value().to_string(), child4.attribute_node("defaultvalue").unwrap().name().to_string(), child4.attribute_node("defaultvalue").unwrap().value().to_string()); - if child4.tag_name().name().to_string().as_str() == "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().to_string().as_str() == "DEFINITION" { - for attr in child2.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - 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())) - } - } - } - } - } - } - } - } - if child2.has_children() { - for child3 in child2.children() { - if child3.is_element() { - if child3.tag_name().name().to_string().as_str() == "MEMBERS" { - print!("\n {:?}: ", child3.tag_name()); - for attr in child3.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child3.has_children() { - for child4 in child3.children() { - if child4.is_element() { - print!("\n {:?}: ", child4.tag_name()); - for attr in child4.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child4.tag_name().name().to_string().as_str() == "MEMBER" { - 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())); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - else if child3.tag_name().name().to_string().as_str() == "ENUMERATION" { - print!("\n {:?}: ", child3.tag_name()); - for attr in child3.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child3.has_children() { - for child4 in child3.children() { - if child4.is_element() { - print!("\n {:?}: ", child4.tag_name()); - for attr in child4.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child4.tag_name().name().to_string().as_str() == "ENUM" { - 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())); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - else if child2.tag_name().name().to_string().as_str() == "MESSAGES" { - for attr in child2.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - if child2.has_children() { - for child3 in child2.children() { - if child3.is_element() { - print!("\n {:?}: ", child3.tag_name()); - if child3.tag_name().name().to_string().as_str() == "MSG" { - for attr in child3.attributes() { - if attr.name() != "comment" { - print!("{:?}={:?} " , attr.name(), attr.value()) - } - } - messages.push(child3); - } - } - } - } - } - } - } - } - } - + + 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 family) = wrapped_family{ + for child in root.children(){ + 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); + } } - - if let Some(ref mut real_family) = family{ - real_family.push_messages(messages); - println!("{:?}",real_family); - return family.unwrap(); - } - else { - panic!("Family is uninitialized.") + return Err(core::fmt::Error); +} + +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() + )); + }); + }); + } + ); + }, + "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" => {}, + _ => {} } }