use crate::*;
use std::{
fmt,
io::{BufRead, Error as ioError},
};
use super::{types::*, utils::*};
pub fn load_pts<IP, P, R>(read: &mut R, ip: &mut IP) -> PtsResult<()>
where
IP: IsPushable<P>,
P: IsBuildable3D,
R: BufRead,
{
let mut line_buffer = Vec::new();
let mut i_line = 0;
let mut n_vertices = None;
let mut n_added = 0;
while let Ok(line) = fetch_line(read, &mut line_buffer) {
i_line += 1;
if line.is_empty() {
continue;
}
match n_vertices {
None => {
let mut words = to_words_skip_empty(line);
n_vertices = Some(
words
.next()
.and_then(|word| from_ascii(word))
.ok_or(PtsError::VertexCount)
.line(i_line, line)?,
);
ip.reserve(n_vertices.unwrap());
}
Some(n) => {
if n_added < n {
let mut words = to_words_skip_empty(line);
let x = words
.next()
.and_then(|word| from_ascii(word))
.ok_or(PtsError::Vertex)
.line(i_line, line)?;
let y = words
.next()
.and_then(|word| from_ascii(word))
.ok_or(PtsError::Vertex)
.line(i_line, line)?;
let z = words
.next()
.and_then(|word| from_ascii(word))
.ok_or(PtsError::Vertex)
.line(i_line, line)?;
ip.push(P::new(x, y, z));
n_added += 1;
} else {
n_added = 0;
let mut words = to_words_skip_empty(line);
n_vertices = Some(
words
.next()
.and_then(|word| from_ascii(word))
.ok_or(PtsError::VertexCount)
.line(i_line, line)?,
);
ip.reserve(n_vertices.unwrap());
}
}
}
}
Ok(())
}
pub enum PtsError {
AccessFile,
VertexCount,
Vertex,
}
pub type PtsResult<T> = IOResult<T, PtsError>;
impl fmt::Debug for PtsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::AccessFile => write!(f, "Unable to access file"),
Self::VertexCount => write!(f, "Unable to parse vertex count"),
Self::Vertex => write!(f, "Unable to parse vertex"),
}
}
}
impl fmt::Display for PtsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<ioError> for PtsError {
fn from(_error: ioError) -> Self {
PtsError::AccessFile
}
}