use fj_math::Point;
use crate::{
objects::{
Curve, GlobalCurve, GlobalEdge, HalfEdge, Surface, SurfaceVertex,
Vertex,
},
stores::{Handle, Stores},
};
use super::{HasPartial, Partial};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub enum MaybePartial<T: HasPartial> {
Full(T),
Partial(T::Partial),
}
impl<T: HasPartial> MaybePartial<T> {
pub fn update_partial(
self,
f: impl FnOnce(T::Partial) -> T::Partial,
) -> Self {
match self {
Self::Partial(partial) => Self::Partial(f(partial)),
_ => self,
}
}
pub fn into_full(self, stores: &Stores) -> T {
match self {
Self::Partial(partial) => partial.build(stores),
Self::Full(full) => full,
}
}
pub fn into_partial(self) -> T::Partial {
match self {
Self::Partial(partial) => partial,
Self::Full(full) => full.to_partial(),
}
}
}
impl<T> From<T> for MaybePartial<T>
where
T: HasPartial,
{
fn from(full: T) -> Self {
Self::Full(full)
}
}
impl MaybePartial<Handle<Curve>> {
pub fn global_form(&self) -> Option<Handle<GlobalCurve>> {
match self {
Self::Full(full) => Some(full.global_form().clone()),
Self::Partial(partial) => {
partial.global_form.clone().map(Into::into)
}
}
}
}
impl MaybePartial<GlobalEdge> {
pub fn curve(&self) -> Option<&Handle<GlobalCurve>> {
match self {
Self::Full(full) => Some(full.curve()),
Self::Partial(partial) => {
partial.curve.as_ref().map(|wrapper| &wrapper.0)
}
}
}
}
impl MaybePartial<HalfEdge> {
pub fn vertices(&self) -> Option<[MaybePartial<Vertex>; 2]> {
match self {
Self::Full(full) => Some(full.vertices().clone().map(Into::into)),
Self::Partial(partial) => partial.vertices.clone(),
}
}
}
impl MaybePartial<SurfaceVertex> {
pub fn position(&self) -> Option<Point<2>> {
match self {
Self::Full(full) => Some(full.position()),
Self::Partial(partial) => partial.position,
}
}
pub fn surface(&self) -> Option<&Handle<Surface>> {
match self {
Self::Full(full) => Some(full.surface()),
Self::Partial(partial) => partial.surface.as_ref(),
}
}
}
impl MaybePartial<Vertex> {
pub fn surface_form(&self) -> Option<MaybePartial<SurfaceVertex>> {
match self {
Self::Full(full) => Some(full.surface_form().clone().into()),
Self::Partial(partial) => partial.surface_form.clone(),
}
}
}