fn parse_structs() -> (HashMap<String, Struct>, Vec<String>) {
    let file = File::open(concat!(env!("CARGO_MANIFEST_DIR"), "/gen_src/vk.xml")).unwrap();
    let reader = BufReader::new(file);
    let parser = EventReader::new(reader);

    let mut structs = HashMap::with_capacity(300);
    let mut struct_order = Vec::with_capacity(300);

    let mut current_struct: Option<Struct> = None;
    let mut struct_start_depth = 0;
    let mut parsing_struct_comment = false;

    let mut current_member: Option<Member> = None;
    let mut member_start_depth = 0;
    let mut parsing_member_type = false;
    let mut parsing_member_name = false;
    let mut parsing_member_array_len = false;
    let mut parsing_member_comment = false;

    let mut depth = 0;

    for e in parser {
        match e {
            Ok(XmlEvent::StartElement { name, attributes, .. }) => {
                let mut type_category = TypeCategory::None;
                if name.local_name == "type" {
                    for attrib in &attributes {
                        if attrib.name.local_name == "category" {
                            type_category = category(&attrib.value);
                        }
                    }
                }
                if type_category == TypeCategory::Struct {
                    current_struct = Some(Struct::new(&attributes));
                    struct_start_depth = depth;
                }
                if let Some(ref mut _st) = current_struct {
                    match name.local_name.as_str() {
                        "member" => {
                            assert!(current_member.is_none());
                            current_member = Some(Member::new(&attributes));
                            member_start_depth = depth;
                        },
                        "type" => {
                            parsing_member_type = true;
                        },
                        "name" => {
                            parsing_member_name = true;
                        },
                        "enum" => {
                            parsing_member_array_len = true;
                        },
                        "comment" => {
                            if current_member.is_some() {
                                parsing_member_comment = true;
                            } else {
                                parsing_struct_comment = true;
                            }
                        },
                        unknown @ _ => panic!("unknown tag: \"{}\"", unknown),
                    }
                    if PRINT {
                        print!("{}<{}", indent(depth), name);
                        for attrib in attributes {
                            print!(" {}=\"{}\"", attrib.name, attrib.value);
                        }
                        print!(">\n");
                    }
                }
                depth += 1;
            },
            Ok(XmlEvent::EndElement { name }) => {
                depth -= 1;
                if PRINT && current_struct.is_some() {
                    println!("{}</{}>", indent(depth), name);
                }
                if name.local_name == "member" && current_struct.is_some() {
                    if depth == member_start_depth {
                        let s = current_struct.as_mut().expect("no current struct");
                        let new_member = current_member.take().expect("no current member");
                        s.add_member(new_member)
                    }
                } else if name.local_name == "type" && current_struct.is_some() {
                    if depth == struct_start_depth {
                        assert!(current_struct.is_some());
                        if let Some(s) = current_struct.take() {
                            let key = s.voodoo_name.clone();
                            struct_order.push(key.clone());
                            structs.insert(key, s);

                        }
                    }
                }
            },
            Ok(XmlEvent::Characters(s)) => {
                if PRINT && current_struct.is_some() {
                    println!("{}{}", indent(depth), s.as_str());
                }
                if let Some(ref mut cur_mem) = current_member {
                    if s.len() > 0 {
                        if parsing_member_type {
                            cur_mem.set_type(s);
                            parsing_member_type = false;
                        } else if parsing_member_name {
                            cur_mem.set_name(s);
                            parsing_member_name = false;
                        } else if parsing_member_array_len {
                            cur_mem.array_len = Some(s);
                            parsing_member_array_len = false;
                        } else if parsing_member_comment {
                            cur_mem.comment = Some(s);
                            parsing_member_comment = false;
                        } else {
                            parse_stray_text(&s, cur_mem);
                            if cur_mem.is_ptr || cur_mem.is_ptr_ptr {
                                current_struct.as_mut().unwrap().contains_ptr = true;
                            }
                        }
                    }
                } else if let Some(ref mut cur_struct) = current_struct {
                    if parsing_struct_comment && s.len() > 0 {
                        cur_struct.comment = String::from(s);
                        parsing_struct_comment = false;
                    }
                }
            },
            Ok(XmlEvent::CData(_s)) => (),
            Ok(XmlEvent::Comment(_s)) => (),
            Ok(XmlEvent::Whitespace(_s)) => (),
            Err(e) => {
                println!("Error: {}", e);
                break;
            },
            _ => {}
        }
    }

    println!("{} structs parsed", structs.len());
    (structs, struct_order)
}
/// Parses a source XML API spec. and pulls out (currently only) structs.
Parses a source XML API spec. and pulls out (currently only) structs.
Parses a source XML API spec . and pulls out ( currently only ) structs .
fn parse_structs() -> (HashMap<String, Struct>, Vec<String>) {
    let file = File::open(concat!(env!("CARGO_MANIFEST_DIR"), "/gen_src/vk.xml")).unwrap();
    let reader = BufReader::new(file);
    let parser = EventReader::new(reader);
    let mut structs = HashMap::with_capacity(300);
    let mut struct_order = Vec::with_capacity(300);
    let mut current_struct: Option<Struct> = None;
    let mut struct_start_depth = 0;
    let mut parsing_struct_comment = false;
    let mut current_member: Option<Member> = None;
    let mut member_start_depth = 0;
    let mut parsing_member_type = false;
    let mut parsing_member_name = false;
    let mut parsing_member_array_len = false;
    let mut parsing_member_comment = false;
    let mut depth = 0;
    for e in parser {
        match e {
            Ok(XmlEvent::StartElement { name, attributes, .. }) => {
                let mut type_category = TypeCategory::None;
                if name.local_name == "type" {
                    for attrib in &attributes {
                        if attrib.name.local_name == "category" {
                            type_category = category(&attrib.value);
                        }
                    }
                }
                if type_category == TypeCategory::Struct {
                    current_struct = Some(Struct::new(&attributes));
                    struct_start_depth = depth;
                }
                if let Some(ref mut _st) = current_struct {
                    match name.local_name.as_str() {
                        "member" => {
                            assert!(current_member.is_none());
                            current_member = Some(Member::new(&attributes));
                            member_start_depth = depth;
                        },
                        "type" => {
                            parsing_member_type = true;
                        },
                        "name" => {
                            parsing_member_name = true;
                        },
                        "enum" => {
                            parsing_member_array_len = true;
                        },
                        "comment" => {
                            if current_member.is_some() {
                                parsing_member_comment = true;
                            } else {
                                parsing_struct_comment = true;
                            }
                        },
                        unknown @ _ => panic!("unknown tag: \"{}\"", unknown),
                    }
                    if PRINT {
                        print!("{}<{}", indent(depth), name);
                        for attrib in attributes {
                            print!(" {}=\"{}\"", attrib.name, attrib.value);
                        }
                        print!(">\n");
                    }
                }
                depth += 1;
            },
            Ok(XmlEvent::EndElement { name }) => {
                depth -= 1;
                if PRINT && current_struct.is_some() {
                    println!("{}</{}>", indent(depth), name);
                }
                if name.local_name == "member" && current_struct.is_some() {
                    if depth == member_start_depth {
                        let s = current_struct.as_mut().expect("no current struct");
                        let new_member = current_member.take().expect("no current member");
                        s.add_member(new_member)
                    }
                } else if name.local_name == "type" && current_struct.is_some() {
                    if depth == struct_start_depth {
                        assert!(current_struct.is_some());
                        if let Some(s) = current_struct.take() {
                            let key = s.voodoo_name.clone();
                            struct_order.push(key.clone());
                            structs.insert(key, s);
                        }
                    }
                }
            },
            Ok(XmlEvent::Characters(s)) => {
                if PRINT && current_struct.is_some() {
                    println!("{}{}", indent(depth), s.as_str());
                }
                if let Some(ref mut cur_mem) = current_member {
                    if s.len() > 0 {
                        if parsing_member_type {
                            cur_mem.set_type(s);
                            parsing_member_type = false;
                        } else if parsing_member_name {
                            cur_mem.set_name(s);
                            parsing_member_name = false;
                        } else if parsing_member_array_len {
                            cur_mem.array_len = Some(s);
                            parsing_member_array_len = false;
                        } else if parsing_member_comment {
                            cur_mem.comment = Some(s);
                            parsing_member_comment = false;
                        } else {
                            parse_stray_text(&s, cur_mem);
                            if cur_mem.is_ptr || cur_mem.is_ptr_ptr {
                                current_struct.as_mut().unwrap().contains_ptr = true;
                            }
                        }
                    }
                } else if let Some(ref mut cur_struct) = current_struct {
                    if parsing_struct_comment && s.len() > 0 {
                        cur_struct.comment = String::from(s);
                        parsing_struct_comment = false;
                    }
                }
            },
            Ok(XmlEvent::CData(_s)) => (),
            Ok(XmlEvent::Comment(_s)) => (),
            Ok(XmlEvent::Whitespace(_s)) => (),
            Err(e) => {
                println!("Error: {}", e);
                break;
            },
            _ => {}
        }
    }
    println!("{} structs parsed", structs.len());
    (structs, struct_order)
}
fn parse_structs ( ) -> ( HashMap < String , Struct > , Vec < String > ) { let file = File :: open ( concat ! ( env ( " " ) " " ) ) . unwrap ( ) ; let reader = BufReader :: new ( file ) ; let parser = EventReader :: new ( reader ) ; let mut structs = HashMap :: with_capacity ( 300 ) ; let mut struct_order = Vec :: with_capacity ( 300 ) ; let mut current_struct : Option < Struct > = None ; let mut struct_start_depth = 0 ; let mut parsing_struct_comment = false ; let mut current_member : Option < Member > = None ; let mut member_start_depth = 0 ; let mut parsing_member_type = false ; let mut parsing_member_name = false ; let mut parsing_member_array_len = false ; let mut parsing_member_comment = false ; let mut depth = 0 ; for e in parser { match e { Ok ( XmlEvent :: StartElement { name , attributes , .. } ) => { let mut type_category = TypeCategory :: None ; if name . local_name == " " { for attrib in & attributes { if attrib . name . local_name == " " { type_category = category ( & attrib . value ) ; } } } if type_category == TypeCategory :: Struct { current_struct = Some ( Struct :: new ( & attributes ) ) ; struct_start_depth = depth ; } if let Some ( ref mut _st ) = current_struct { match name . local_name . as_str ( ) { " " => { assert ! ( current_member is_none ( ) ) ; current_member = Some ( Member :: new ( & attributes ) ) ; member_start_depth = depth ; } , " " => { parsing_member_type = true ; } , " " => { parsing_member_name = true ; } , " " => { parsing_member_array_len = true ; } , " " => { if current_member . is_some ( ) { parsing_member_comment = true ; } else { parsing_struct_comment = true ; } } , unknown @ _ => panic ! ( " \" \" " unknown ) , } if PRINT { print ! ( " " indent ( depth ) name ) ; for attrib in attributes { print ! ( " \" \" " attrib name attrib value ) ; } print ! ( " \n " ) ; } } depth += 1 ; } , Ok ( XmlEvent :: EndElement { name } ) => { depth -= 1 ; if PRINT && current_struct . is_some ( ) { println ! ( " " indent ( depth ) name ) ; } if name . local_name == " " && current_struct . is_some ( ) { if depth == member_start_depth { let s = current_struct . as_mut ( ) . expect ( " " ) ; let new_member = current_member . take ( ) . expect ( " " ) ; s . add_member ( new_member ) } } else if name . local_name == " " && current_struct . is_some ( ) { if depth == struct_start_depth { assert ! ( current_struct is_some ( ) ) ; if let Some ( s ) = current_struct . take ( ) { let key = s . voodoo_name . clone ( ) ; struct_order . push ( key . clone ( ) ) ; structs . insert ( key , s ) ; } } } } , Ok ( XmlEvent :: Characters ( s ) ) => { if PRINT && current_struct . is_some ( ) { println ! ( " " indent ( depth ) s as_str ( ) ) ; } if let Some ( ref mut cur_mem ) = current_member { if s . len ( ) > 0 { if parsing_member_type { cur_mem . set_type ( s ) ; parsing_member_type = false ; } else if parsing_member_name { cur_mem . set_name ( s ) ; parsing_member_name = false ; } else if parsing_member_array_len { cur_mem . array_len = Some ( s ) ; parsing_member_array_len = false ; } else if parsing_member_comment { cur_mem . comment = Some ( s ) ; parsing_member_comment = false ; } else { parse_stray_text ( & s , cur_mem ) ; if cur_mem . is_ptr || cur_mem . is_ptr_ptr { current_struct . as_mut ( ) . unwrap ( ) . contains_ptr = true ; } } } } else if let Some ( ref mut cur_struct ) = current_struct { if parsing_struct_comment && s . len ( ) > 0 { cur_struct . comment = String :: from ( s ) ; parsing_struct_comment = false ; } } } , Ok ( XmlEvent :: CData ( _s ) ) => ( ) , Ok ( XmlEvent :: Comment ( _s ) ) => ( ) , Ok ( XmlEvent :: Whitespace ( _s ) ) => ( ) , Err ( e ) => { println ! ( " " e ) ; break ; } , _ => { } } } println ! ( " " structs len ( ) ) ; ( structs , struct_order ) }
Parses a source XML API spec.
Parses a source XML API spec .