honeycomb_core/cmap/dim3/sews/
mod.rs

1mod one;
2mod three;
3mod two;
4
5use crate::cmap::{CMap3, DartIdType, SewError};
6use crate::geometry::CoordsFloat;
7use crate::stm::{atomically_with_err, Transaction, TransactionClosureResult};
8
9/// # **Sew operations**
10impl<T: CoordsFloat> CMap3<T> {
11    /// `I`-sew operator.
12    ///
13    /// # Description
14    ///
15    /// This operation corresponds to:
16    /// - coherently linking two darts via their *β* images,
17    /// - merging the attributes associated to their respective original `I`-cells.
18    ///
19    /// For a thorough explanation of this operation, its hypothesis & consequences, refer
20    /// to the [user guide][UG].
21    ///
22    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
23    ///
24    /// # Arguments
25    ///
26    /// - `const I: u8` -- Sew dimension.
27    /// - `trans: &mut Transaction` -- Transaction associated to the operation.
28    /// - `ld: DartIdType` -- First dart ID.
29    /// - `rd: DartIdType` -- Second dart ID.
30    ///
31    /// # Errors
32    ///
33    /// This variant will abort the sew operation and raise an error if:
34    /// - the transaction cannot be completed,
35    /// - one (or more) attribute merge fails,
36    /// - for `I == 3`: orientation is inconsistent.
37    ///
38    /// The returned error can be used in conjunction with transaction control to avoid any
39    /// modifications in case of failure at attribute level. The user can then choose to retry or
40    /// abort as he wishes using `Transaction::with_control`.
41    ///
42    /// # Panics
43    ///
44    /// The method may panic if:
45    /// - `I >= 4` or `I == 0`,
46    /// - the two darts are not `I`-sewable.
47    pub fn sew<const I: u8>(
48        &self,
49        trans: &mut Transaction,
50        ld: DartIdType,
51        rd: DartIdType,
52    ) -> TransactionClosureResult<(), SewError> {
53        // these assertions + match on a const are optimized away
54        assert!(I < 4);
55        assert_ne!(I, 0);
56        match I {
57            1 => self.one_sew(trans, ld, rd),
58            2 => self.two_sew(trans, ld, rd),
59            3 => self.three_sew(trans, ld, rd),
60            _ => unreachable!(),
61        }
62    }
63
64    /// `I`-unsew operator.
65    ///
66    /// # Description
67    ///
68    /// This operation corresponds to:
69    /// - unlinking two darts by resetting their *β* images,
70    /// - splitting the attributes associated to the original `I`-cell.
71    ///
72    /// For a thorough explanation of this operation, its hypothesis & consequences, refer
73    /// to the [user guide][UG].
74    ///
75    /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
76    ///
77    /// # Arguments
78    ///
79    /// - `const I: u8` -- Unsew dimension.
80    /// - `trans: &mut Transaction` -- Transaction associated to the operation.
81    /// - `ld: DartIdType` -- First dart ID.
82    ///
83    /// The second dart ID is fetched using `I` and `ld`.
84    ///
85    /// # Errors    
86    ///
87    /// This variant will abort the unsew operation and raise an error if:
88    /// - the transaction cannot be completed,
89    /// - one (or more) attribute split fails.
90    ///
91    /// The returned error can be used in conjunction with transaction control to avoid any
92    /// modifications in case of failure at attribute level. The user can then choose to retry or
93    /// abort as he wishes using `Transaction::with_control`.
94    ///
95    /// # Panics
96    ///
97    /// The method may panic if:
98    /// - `I >= 4` or `I == 0`,
99    /// - `ld` is already `I`-free.
100    pub fn unsew<const I: u8>(
101        &self,
102        trans: &mut Transaction,
103        ld: DartIdType,
104    ) -> TransactionClosureResult<(), SewError> {
105        // these assertions + match on a const are optimized away
106        assert!(I < 4);
107        assert_ne!(I, 0);
108        match I {
109            1 => self.one_unsew(trans, ld),
110            2 => self.two_unsew(trans, ld),
111            3 => self.three_unsew(trans, ld),
112            _ => unreachable!(),
113        }
114    }
115
116    #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
117    /// `I`-sew operator.
118    ///
119    /// This variant is equivalent to [`sew`][Self::sew], but internally uses a transaction that
120    /// will be retried until validated.
121    pub fn force_sew<const I: u8>(&self, ld: DartIdType, rd: DartIdType) -> Result<(), SewError> {
122        // these assertions + match on a const are optimized away
123        assert!(I < 4);
124        assert_ne!(I, 0);
125        match I {
126            1 => atomically_with_err(|trans| self.one_sew(trans, ld, rd)),
127            2 => atomically_with_err(|trans| self.two_sew(trans, ld, rd)),
128            3 => atomically_with_err(|trans| self.three_sew(trans, ld, rd)),
129            _ => unreachable!(),
130        }
131    }
132
133    #[allow(clippy::missing_errors_doc, clippy::missing_panics_doc)]
134    /// `I`-unsew operator.
135    ///
136    /// This variant is equivalent to [`unsew`][Self::unsew], but internally uses a transaction that
137    /// will be retried until validated.
138    pub fn force_unsew<const I: u8>(&self, ld: DartIdType) -> Result<(), SewError> {
139        // these assertions + match on a const are optimized away
140        assert!(I < 4);
141        assert_ne!(I, 0);
142        match I {
143            1 => atomically_with_err(|trans| self.one_unsew(trans, ld)),
144            2 => atomically_with_err(|trans| self.two_unsew(trans, ld)),
145            3 => atomically_with_err(|trans| self.three_unsew(trans, ld)),
146            _ => unreachable!(),
147        }
148    }
149}