use crate::contour::Contour;
use compare_variables::*;
use core::result;
pub type Result<T> = result::Result<T, Error>;
#[derive(Clone, Debug, PartialEq)]
pub enum ShapeConstructorError<T> {
EmptyVec,
EmptyContour {
input: T,
idx: usize,
},
HoleOutsideContour {
input: T,
idx: usize,
},
HoleInsideHole {
input: T,
outer_hole_idx: usize,
inner_hole_idx: usize,
},
Intersection {
input: T,
intersection: crate::composite::Intersection,
},
}
impl<T> std::fmt::Display for ShapeConstructorError<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ShapeConstructorError::EmptyVec => write!(f, "given contour vector was empty"),
ShapeConstructorError::EmptyContour { input: _, idx } => {
write!(f, "contour {} is empty", idx)
}
ShapeConstructorError::HoleOutsideContour { input: _, idx } => {
write!(
f,
"hole contour {} is outside the outer contour of the shape",
idx
)
}
ShapeConstructorError::HoleInsideHole {
input: _,
outer_hole_idx,
inner_hole_idx,
} => write!(
f,
"hole contour {} contains the hole at index {}",
outer_hole_idx, inner_hole_idx
),
ShapeConstructorError::Intersection {
input: _,
intersection,
} => {
write!(
f,
"segment {} of contour {} intersects segment {} of contour {} at point x = {}, y = {}",
intersection.left.segment_idx,
intersection.left.contour_idx,
intersection.right.segment_idx,
intersection.right.contour_idx,
intersection.point[0],
intersection.point[1]
)
}
}
}
}
impl<T: std::fmt::Debug> std::error::Error for ShapeConstructorError<T> {}
#[derive(Debug)]
pub struct Error(pub Box<ErrorType>);
impl Error {
pub fn cause(&self) -> &ErrorType {
return &*self.0;
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return self.0.fmt(f);
}
}
impl std::error::Error for Error {}
impl From<ErrorType> for Error {
fn from(err: ErrorType) -> Self {
return Error(Box::new(err));
}
}
impl From<ComparisonError<f64>> for Error {
fn from(err: ComparisonError<f64>) -> Self {
return ErrorType::ComparisonError(err).into();
}
}
#[derive(Debug)]
pub enum ErrorType {
ComparisonError(ComparisonError<f64>),
Collinear([[f64; 2]; 3]),
PointsIdentical {
start: [f64; 2],
stop: [f64; 2],
},
NewShape(ShapeConstructorError<Vec<Contour>>),
AddHole(ShapeConstructorError<Contour>),
}
impl std::fmt::Display for ErrorType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ErrorType::ComparisonError(err) => err.fmt(f),
ErrorType::Collinear(pts) => {
write!(f, "given points {:?} are collinear.", pts)
}
ErrorType::PointsIdentical { start, stop } => {
write!(
f,
"start point {:?} and end point {:?} are identical",
start, stop
)
}
ErrorType::NewShape(err) => {
return err.fmt(f);
}
ErrorType::AddHole(err) => {
return err.fmt(f);
}
}
}
}
impl std::error::Error for ErrorType {}
impl From<ShapeConstructorError<Vec<Contour>>> for ErrorType {
fn from(value: ShapeConstructorError<Vec<Contour>>) -> Self {
return ErrorType::NewShape(value);
}
}
impl From<ShapeConstructorError<Contour>> for ErrorType {
fn from(value: ShapeConstructorError<Contour>) -> Self {
return ErrorType::AddHole(value);
}
}
impl From<ShapeConstructorError<Vec<Contour>>> for Error {
fn from(value: ShapeConstructorError<Vec<Contour>>) -> Self {
return ErrorType::from(value).into();
}
}
impl From<ShapeConstructorError<Contour>> for Error {
fn from(value: ShapeConstructorError<Contour>) -> Self {
return ErrorType::from(value).into();
}
}