Parse rewrite using recursion #4
1 changed files with 149 additions and 158 deletions
307
src/main.rs
307
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<String> = 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<oop::Family> = None;
|
||||
let mut family_name: String;
|
||||
fn new_parse(doc:&roxmltree::Document) -> Result<oop::Family,core::fmt::Error>{
|
||||
let mut wrapped_family:Option<oop::Family> = 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue