use crate::{
geometry::Geometry,
objects::{
Curve, Cycle, Face, HalfEdge, Objects, Region, Shell, Sketch, Solid,
Surface, Vertex,
},
storage::{Handle, HandleWrapper, ObjectId},
validate::Validate,
validation::{ValidationConfig, ValidationError},
};
macro_rules! any_object {
($($ty:ident, $name:expr, $store:ident;)*) => {
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum AnyObject<F: Form> {
$(
#[doc = concat!("A ", $name)]
$ty(F::Form<$ty>),
)*
}
impl AnyObject<Stored> {
pub fn id(&self) -> ObjectId {
match self {
$(
Self::$ty(handle) => handle.id(),
)*
}
}
pub fn validate(&self,
config: &ValidationConfig,
errors: &mut Vec<ValidationError>,
geometry: &Geometry,
) {
match self {
$(
Self::$ty(object) => object.validate(
config,
errors,
geometry,
),
)*
}
}
}
impl AnyObject<AboutToBeStored> {
pub fn insert(self, objects: &mut Objects) -> AnyObject<Stored> {
match self {
$(
Self::$ty((handle, object)) => {
objects.$store.insert(
handle.clone().into(), object
);
handle.0.into()
}
)*
}
}
}
impl From<AnyObject<AboutToBeStored>> for AnyObject<Stored> {
fn from(object: AnyObject<AboutToBeStored>) -> Self {
match object {
$(
AnyObject::$ty((handle, _)) => Self::$ty(handle.into()),
)*
}
}
}
$(
impl From<$ty> for AnyObject<Bare> {
fn from(object: $ty) -> Self {
Self::$ty(object)
}
}
impl From<Handle<$ty>> for AnyObject<Stored> {
fn from(object: Handle<$ty>) -> Self {
Self::$ty(object.into())
}
}
impl From<(Handle<$ty>, $ty)> for AnyObject<AboutToBeStored> {
fn from((handle, object): (Handle<$ty>, $ty)) -> Self {
Self::$ty((handle.into(), object))
}
}
)*
};
}
any_object!(
Curve, "curve", curves;
Cycle, "cycle", cycles;
Face, "face", faces;
HalfEdge, "half-edge", half_edges;
Region, "region", regions;
Shell, "shell", shells;
Sketch, "sketch", sketches;
Solid, "solid", solids;
Surface, "surface", surfaces;
Vertex, "vertex", vertices;
);
pub trait Form {
type Form<T>;
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Bare;
impl Form for Bare {
type Form<T> = T;
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct Stored;
impl Form for Stored {
type Form<T> = HandleWrapper<T>;
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct AboutToBeStored;
impl Form for AboutToBeStored {
type Form<T> = (HandleWrapper<T>, T);
}