thdmaker 0.0.4

A comprehensive 3D file format library supporting AMF, STL, 3MF and other 3D manufacturing formats
Documentation
use std::io::BufRead;
use quick_xml::events::{BytesStart, Event};
use quick_xml::Reader;
use super::error::{Error, Result};
use super::define::trianglesets::*;

impl TriangleSets {
    pub fn parse<R: BufRead>(reader: &mut Reader<R>) -> Result<Self> {
        let mut triangle_sets = Vec::new();
        let mut buf = Vec::new();
    
        loop {
            match reader.read_event_into(&mut buf) {
                Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"triangleset" => {
                    let set = TriangleSet::parse(reader, e)?;
                    triangle_sets.push(set);
                }
                Ok(Event::Empty(ref e)) if e.local_name().as_ref() == b"triangleset" => {
                    let set = TriangleSet::attributes(e)?;
                    triangle_sets.push(set);
                }
                Ok(Event::End(ref e)) if e.local_name().as_ref() == b"trianglesets" => break,
                Ok(Event::Eof) => return Err(Error::UnexpectedEofIn("trianglesets".to_string())),
                Ok(_) => {}
                Err(e) => return Err(Error::Xml(e)),
            }
            buf.clear();
        }
    
        Ok(Self { triangle_sets })
    }
}

impl TriangleSet {
    fn parse<R: BufRead>(reader: &mut Reader<R>, elem: &BytesStart) -> Result<Self> {
        let mut set = Self::attributes(elem)?;
        let mut buf = Vec::new();
    
        loop {
            match reader.read_event_into(&mut buf) {
                Ok(Event::Empty(ref e)) if e.local_name().as_ref() == b"ref" => {
                    let r = TriangleRef::parse(e)?;
                    set.r#ref.push(r);
                }
                Ok(Event::Empty(ref e)) if e.local_name().as_ref() == b"refrange" => {
                    let range = TriangleRefRange::parse(e)?;
                    set.refrange.push(range);
                }
                Ok(Event::End(ref e)) if e.local_name().as_ref() == b"triangleset" => break,
                Ok(Event::Eof) => return Err(Error::UnexpectedEofIn("triangleset".to_string())),
                Ok(_) => {}
                Err(e) => return Err(Error::Xml(e)),
            }
            buf.clear();
        }
    
        Ok(set)
    }

    fn attributes(elem: &BytesStart) -> Result<Self> {
        let mut name = String::new();
        let mut identifier = String::new();
    
        for attr in elem.attributes().flatten() {
            let key = attr.key.as_ref();
            let value = attr.unescape_value()?;
    
            match key {
                b"name" => name = value.to_string(),
                b"identifier" => identifier = value.to_string(),
                _ => {}
            }
        }
    
        Ok(Self {
            name,
            identifier,
            r#ref: Vec::new(),
            refrange: Vec::new(),
        })
    }
}

impl TriangleRef {
    fn parse(elem: &BytesStart) -> Result<Self> {
        let mut index = 0usize;
    
        for attr in elem.attributes().flatten() {
            let key = attr.key.as_ref();
            let value = attr.unescape_value()?;
    
            if key == b"index" {
                index = value.parse()?;
            }
        }
    
        Ok(Self { index })
    }
}

impl TriangleRefRange {
    fn parse(elem: &BytesStart) -> Result<Self> {
        let mut start_index = 0usize;
        let mut end_index = 0usize;
    
        for attr in elem.attributes().flatten() {
            let key = attr.key.as_ref();
            let value = attr.unescape_value()?;
    
            match key {
                b"startindex" => start_index = value.parse()?,
                b"endindex" => end_index = value.parse()?,
                _ => {}
            }
        }
    
        Ok(Self { start_index, end_index })
    }
}