fj_core/operations/update/
shell.rs

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