use crate::{
objects::{
Cycle, Face, GlobalEdge, HalfEdge, Shell, Sketch, Solid, Surface,
Vertex,
},
services::Services,
storage::Handle,
};
use super::{Polygon, TetrahedronShell};
pub trait Insert: Sized {
type Inserted;
fn insert(self, services: &mut Services) -> Self::Inserted;
}
macro_rules! impl_insert {
($($ty:ty, $store:ident;)*) => {
$(
impl Insert for $ty {
type Inserted = Handle<Self>;
fn insert(self, services: &mut Services) -> Self::Inserted {
let handle = services.objects.$store.reserve();
let object = (handle.clone(), self).into();
services.insert_object(object);
handle
}
}
)*
};
}
impl_insert!(
Cycle, cycles;
Face, faces;
GlobalEdge, global_edges;
HalfEdge, half_edges;
Shell, shells;
Sketch, sketches;
Solid, solids;
Surface, surfaces;
Vertex, vertices;
);
pub trait IsInserted {
type T<T>;
}
pub struct IsInsertedYes;
impl IsInserted for IsInsertedYes {
type T<T> = Handle<T>;
}
pub struct IsInsertedNo;
impl IsInserted for IsInsertedNo {
type T<T> = T;
}
impl<const D: usize> Insert for Polygon<D, IsInsertedNo> {
type Inserted = Polygon<D, IsInsertedYes>;
fn insert(self, services: &mut Services) -> Self::Inserted {
Polygon {
face: self.face.insert(services),
edges: self.edges,
vertices: self.vertices,
}
}
}
impl Insert for TetrahedronShell<IsInsertedNo> {
type Inserted = TetrahedronShell<IsInsertedYes>;
fn insert(self, services: &mut Services) -> Self::Inserted {
TetrahedronShell {
shell: self.shell.insert(services),
abc: self.abc,
bad: self.bad,
dac: self.dac,
cbd: self.cbd,
}
}
}