use crate::{
objects::{Cycle, Region},
storage::Handle,
};
pub trait UpdateRegion {
#[must_use]
fn update_exterior(
&self,
update: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self;
#[must_use]
fn add_interiors(
&self,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
) -> Self;
#[must_use]
fn update_interior(
&self,
handle: &Handle<Cycle>,
update: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self;
#[must_use]
fn replace_interior<const N: usize>(
&self,
handle: &Handle<Cycle>,
replace: impl FnOnce(&Handle<Cycle>) -> [Handle<Cycle>; N],
) -> Self;
}
impl UpdateRegion for Region {
fn update_exterior(
&self,
update: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self {
let exterior = update(self.exterior());
Region::new(exterior, self.interiors().iter().cloned(), self.color())
}
fn add_interiors(
&self,
interiors: impl IntoIterator<Item = Handle<Cycle>>,
) -> Self {
let interiors = self.interiors().iter().cloned().chain(interiors);
Region::new(self.exterior().clone(), interiors, self.color())
}
fn update_interior(
&self,
handle: &Handle<Cycle>,
update: impl FnOnce(&Handle<Cycle>) -> Handle<Cycle>,
) -> Self {
let interiors = self
.interiors()
.replace(handle, [update(handle)])
.expect("Cycle not found");
Region::new(self.exterior().clone(), interiors, self.color())
}
fn replace_interior<const N: usize>(
&self,
handle: &Handle<Cycle>,
replace: impl FnOnce(&Handle<Cycle>) -> [Handle<Cycle>; N],
) -> Self {
let interiors = self
.interiors()
.replace(handle, replace(handle))
.expect("Cycle not found");
Region::new(self.exterior().clone(), interiors, self.color())
}
}