fj_core/operations/update/
region.rs

1use crate::{
2    objects::{Cycle, Region},
3    operations::{derive::DeriveFrom, insert::Insert},
4    storage::Handle,
5    Core,
6};
7
8/// Update a [`Region`]
9pub trait UpdateRegion {
10    /// Update the exterior of the region
11    #[must_use]
12    fn update_exterior<T>(
13        &self,
14        update: impl FnOnce(&Handle<Cycle>, &mut Core) -> T,
15        core: &mut Core,
16    ) -> Self
17    where
18        T: Insert<Inserted = Handle<Cycle>>;
19
20    /// Add the provided interiors to the region
21    #[must_use]
22    fn add_interiors<T>(
23        &self,
24        interiors: impl IntoIterator<Item = T>,
25        core: &mut Core,
26    ) -> Self
27    where
28        T: Insert<Inserted = Handle<Cycle>>;
29
30    /// Update an interior cycle of the region
31    ///
32    /// # Panics
33    ///
34    /// Panics, if the object can't be found.
35    ///
36    /// Panics, if the update results in multiple handles referencing the same object.
37    #[must_use]
38    fn update_interior<T, R>(
39        &self,
40        handle: &Handle<Cycle>,
41        update: impl FnOnce(&Handle<Cycle>, &mut Core) -> R,
42        core: &mut Core,
43    ) -> Self
44    where
45        T: Insert<Inserted = Handle<Cycle>>,
46        R: IntoIterator<Item = T>;
47}
48
49impl UpdateRegion for Region {
50    fn update_exterior<T>(
51        &self,
52        update: impl FnOnce(&Handle<Cycle>, &mut Core) -> T,
53        core: &mut Core,
54    ) -> Self
55    where
56        T: Insert<Inserted = Handle<Cycle>>,
57    {
58        let exterior = update(self.exterior(), core)
59            .insert(core)
60            .derive_from(self.exterior(), core);
61        Region::new(exterior, self.interiors().iter().cloned())
62    }
63
64    fn add_interiors<T>(
65        &self,
66        interiors: impl IntoIterator<Item = T>,
67        core: &mut Core,
68    ) -> Self
69    where
70        T: Insert<Inserted = Handle<Cycle>>,
71    {
72        let interiors = interiors.into_iter().map(|cycle| cycle.insert(core));
73        let interiors = self.interiors().iter().cloned().chain(interiors);
74        Region::new(self.exterior().clone(), interiors)
75    }
76
77    fn update_interior<T, R>(
78        &self,
79        handle: &Handle<Cycle>,
80        update: impl FnOnce(&Handle<Cycle>, &mut Core) -> R,
81        core: &mut Core,
82    ) -> Self
83    where
84        T: Insert<Inserted = Handle<Cycle>>,
85        R: IntoIterator<Item = T>,
86    {
87        let interiors = self
88            .interiors()
89            .replace(
90                handle,
91                update(handle, core).into_iter().map(|object| {
92                    object.insert(core).derive_from(handle, core)
93                }),
94            )
95            .expect("Cycle not found");
96        Region::new(self.exterior().clone(), interiors)
97    }
98}