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}