honeycomb_core/cmap/dim3/links/mod.rs
1mod one;
2mod three;
3mod two;
4
5use crate::cmap::{CMap3, DartIdType, LinkError};
6use crate::geometry::CoordsFloat;
7use crate::stm::{Transaction, TransactionClosureResult};
8
9/// # **Link operations**
10impl<T: CoordsFloat> CMap3<T> {
11 /// `I`-link operator.
12 ///
13 /// # Description
14 ///
15 /// This operation corresponds to coherently linking two darts via their *β* images. Unlike
16 /// sewing, this does not alter associated attributes. For a thorough explanation of this
17 /// operation, its hypothesis & consequences, refer to the [user guide][UG].
18 ///
19 /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
20 ///
21 /// # Arguments
22 ///
23 /// - `const I: u8` -- Link dimension.
24 /// - `t: &mut Transaction` -- Transaction associated to the operation.
25 /// - `lhs_dart_id: DartIdType` -- First dart ID.
26 /// - `rhs_dart_id: DartIdType` -- Second dart ID.
27 ///
28 /// # Errors
29 ///
30 /// This method should be called in a transactional context. The `Result` is then used to
31 /// validate the transaction; Errors should not be processed manually, only processed via the
32 /// `?` operator. The policy in case of failure can be defined when creating the transaction,
33 /// using `Transaction::with_control`.
34 ///
35 /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
36 /// more detail about the latter.
37 ///
38 /// # Panics
39 ///
40 /// The method may panic if:
41 /// - `I >= 4` or `I == 0`,
42 /// - the two darts are not `I`-linkable.
43 pub fn link<const I: u8>(
44 &self,
45 t: &mut Transaction,
46 lhs_dart_id: DartIdType,
47 rhs_dart_id: DartIdType,
48 ) -> TransactionClosureResult<(), LinkError> {
49 // these assertions + match on a const are optimized away
50 assert!(I < 4);
51 assert_ne!(I, 0);
52 match I {
53 1 => self.one_link(t, lhs_dart_id, rhs_dart_id),
54 2 => self.two_link(t, lhs_dart_id, rhs_dart_id),
55 3 => self.three_link(t, lhs_dart_id, rhs_dart_id),
56 _ => unreachable!(),
57 }
58 }
59
60 /// `I`-unlink operator.
61 ///
62 /// # Description
63 ///
64 /// This operation corresponds to unlinking two darts by resetting their *β* images. Unlike
65 /// unsewing, this does not alter associated attributes. For a thorough explanation of this
66 /// operation, its hypothesis & consequences, refer to the [user guide][UG].
67 ///
68 /// [UG]: https://lihpc-computational-geometry.github.io/honeycomb/user-guide/definitions/sew.html
69 ///
70 /// # Arguments
71 ///
72 /// - `const I: u8` -- Unlink dimension.
73 /// - `t: &mut Transaction` -- Transaction associated to the operation.
74 /// - `lhs_dart_id: DartIdType` -- First dart ID.
75 ///
76 /// The second dart ID is fetched using `I` and `lhs_dart_id`.
77 ///
78 /// # Errors
79 ///
80 /// This method should be called in a transactional context. The `Result` is then used to
81 /// validate the transaction; Errors should not be processed manually, only processed via the
82 /// `?` operator. The policy in case of failure can be defined when creating the transaction,
83 /// using `Transaction::with_control`.
84 ///
85 /// # Panics
86 ///
87 /// The method may panic if:
88 /// - `I >= 4` or `I == 0`,
89 /// - `lhs_dart_id` is already `I`-free.
90 pub fn unlink<const I: u8>(
91 &self,
92 t: &mut Transaction,
93 lhs_dart_id: DartIdType,
94 ) -> TransactionClosureResult<(), LinkError> {
95 // these assertions + match on a const are optimized away
96 assert!(I < 4);
97 assert_ne!(I, 0);
98 match I {
99 1 => self.one_unlink(t, lhs_dart_id),
100 2 => self.two_unlink(t, lhs_dart_id),
101 3 => self.three_unlink(t, lhs_dart_id),
102 _ => unreachable!(),
103 }
104 }
105
106 /// `I`-link operator.
107 ///
108 /// This variant is equivalent to [`link`][Self::link], but internally uses a transaction that
109 /// will be retried until validated.
110 ///
111 /// # Errors
112 ///
113 /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
114 /// more detail about the latter.
115 ///
116 /// # Panics
117 ///
118 /// The method may panic if:
119 /// - `I >= 4` or `I == 0`,
120 /// - `lhs_dart_id` is already `I`-free.
121 pub fn force_link<const I: u8>(
122 &self,
123 lhs_dart_id: DartIdType,
124 rhs_dart_id: DartIdType,
125 ) -> Result<(), LinkError> {
126 // these assertions + match on a const are optimized away
127 assert!(I < 4);
128 assert_ne!(I, 0);
129 match I {
130 1 => self.force_one_link(lhs_dart_id, rhs_dart_id),
131 2 => self.force_two_link(lhs_dart_id, rhs_dart_id),
132 3 => self.force_three_link(lhs_dart_id, rhs_dart_id),
133 _ => unreachable!(),
134 }
135 }
136
137 /// `I`-unlink operator.
138 ///
139 /// This variant is equivalent to [`unlink`][Self::unlink], but internally uses a transaction
140 /// that will be retried until validated.
141 ///
142 /// # Errors
143 ///
144 /// It may return an error if the transaction fails or if the link fails; See [`LinkError`] for
145 /// more detail about the latter.
146 ///
147 /// # Panics
148 ///
149 /// The method may panic if:
150 /// - `I >= 4` or `I == 0`,
151 /// - `lhs_dart_id` is already `I`-free.
152 pub fn force_unlink<const I: u8>(&self, lhs_dart_id: DartIdType) -> Result<(), LinkError> {
153 // these assertions + match on a const are optimized away
154 assert!(I < 4);
155 assert_ne!(I, 0);
156 match I {
157 1 => self.force_one_unlink(lhs_dart_id),
158 2 => self.force_two_unlink(lhs_dart_id),
159 3 => self.force_three_unlink(lhs_dart_id),
160 _ => unreachable!(),
161 }
162 }
163}