use crate::*;
use std::{
fmt,
io::{BufRead, Error as ioError, Write},
};
use super::{types::*, utils::*};
pub fn save_xy<RA, P, W>(write: &mut W, ra: &RA, delim_coord: &str, delim_pos: &str) -> XyResult<()>
where
RA: IsRandomAccessible<P>,
P: Is2D,
W: Write,
{
let n = ra.len();
for i in 0..n {
let ref p = ra[i];
let buffer = p.x().to_string() + delim_coord + &p.y().to_string() + delim_pos;
write.write_all(buffer.as_bytes())?;
}
Ok(())
}
pub fn load_xy<IP, P, R>(read: &mut R, ip: &mut IP) -> XyIOResult<()>
where
IP: IsPushable<P>,
P: IsBuildable2D,
R: BufRead,
{
let mut delim_determined = false;
let mut delim = 0;
let mut line_buffer = Vec::new();
let mut i_line = 0;
while let Ok(line) = fetch_line(read, &mut line_buffer) {
i_line += 1;
if !delim_determined {
delim = estimate_delimiter(1, line)
.ok_or(XyError::EstimateDelimiter)
.line(i_line, line)?;
delim_determined = true;
}
let mut words = line.split(|x| *x == delim).skip_empty();
let x = words
.next()
.and_then(|word| from_ascii(word))
.ok_or(XyError::Vertex)
.line(i_line, line)?;
let y = words
.next()
.and_then(|word| from_ascii(word))
.ok_or(XyError::Vertex)
.line(i_line, line)?;
ip.push(P::new(x, y));
}
Ok(())
}
pub enum XyError {
EstimateDelimiter,
AccessFile,
Vertex,
}
pub type XyResult<T> = std::result::Result<T, XyError>;
pub type XyIOResult<T> = IOResult<T, XyError>;
impl fmt::Debug for XyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Vertex => write!(f, "Unable to parse vertex"),
Self::AccessFile => write!(f, "Unable to access file"),
Self::EstimateDelimiter => write!(f, "Unable to estimate delimiter"),
}
}
}
impl fmt::Display for XyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<ioError> for XyError {
fn from(_error: ioError) -> Self {
XyError::AccessFile
}
}