use crate::{
objects::{
Cycle, Face, GlobalEdge, HalfEdge, Objects, Shell, Sketch, Solid,
Surface, Vertex,
},
storage::{Handle, HandleWrapper, ObjectId},
validate::{Validate, ValidationError},
};
macro_rules! object {
($($ty:ident, $name:expr, $store:ident;)*) => {
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum Object<F: Form> {
$(
#[doc = concat!("A ", $name)]
$ty(F::Form<$ty>),
)*
}
impl Object<BehindHandle> {
pub fn id(&self) -> ObjectId {
match self {
$(
Self::$ty(handle) => handle.id(),
)*
}
}
pub fn validate(&self, errors: &mut Vec<ValidationError>) {
match self {
$(
Self::$ty(object) => object.validate(errors),
)*
}
}
}
impl Object<WithHandle> {
pub fn insert(self, objects: &mut Objects) -> Object<BehindHandle> {
match self {
$(
Self::$ty((handle, object)) => {
objects.$store.insert(
handle.clone().into(), object
);
handle.0.into()
}
)*
}
}
}
impl From<Object<WithHandle>> for Object<BehindHandle> {
fn from(object: Object<WithHandle>) -> Self {
match object {
$(
Object::$ty((handle, _)) => Self::$ty(handle.into()),
)*
}
}
}
$(
impl From<$ty> for Object<Bare> {
fn from(object: $ty) -> Self {
Self::$ty(object)
}
}
impl From<Handle<$ty>> for Object<BehindHandle> {
fn from(object: Handle<$ty>) -> Self {
Self::$ty(object.into())
}
}
impl From<(Handle<$ty>, $ty)> for Object<WithHandle> {
fn from((handle, object): (Handle<$ty>, $ty)) -> Self {
Self::$ty((handle.into(), object))
}
}
)*
};
}
object!(
Cycle, "cycle", cycles;
Face, "face", faces;
GlobalEdge, "global edge", global_edges;
HalfEdge, "half-edge", half_edges;
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 BehindHandle;
impl Form for BehindHandle {
type Form<T> = HandleWrapper<T>;
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct WithHandle;
impl Form for WithHandle {
type Form<T> = (HandleWrapper<T>, T);
}