honeycomb_core/cmap/dim3/embed.rs
1//! Attribute operations implementation
2//!
3//! This module contains code used to implement operations on the embedded data associated to the
4//! map. This includes operations regarding vertices as well as (in the future) user-defined
5//! generic attributes
6
7use crate::attributes::{
8 AttributeBind, AttributeStorage, AttributeUpdate, UnknownAttributeStorage,
9};
10use crate::cmap::{CMap3, VertexIdType};
11use crate::geometry::{CoordsFloat, Vertex3};
12use crate::stm::{atomically, StmClosureResult, Transaction};
13
14/// ## **Built-in vertex-related methods**
15impl<T: CoordsFloat> CMap3<T> {
16 /// Return the current number of vertices.
17 #[must_use = "unused return value"]
18 pub fn n_vertices(&self) -> usize {
19 self.vertices.n_attributes()
20 }
21
22 #[allow(clippy::missing_errors_doc)]
23 /// Return the vertex associated to a given identifier.
24 ///
25 /// # Return / Errors
26 ///
27 /// This method is meant to be called in a context where the returned `Result` is used to
28 /// validate the transaction passed as argument. Errors should not be processed manually,
29 /// only processed via the `?` operator.
30 ///
31 /// This method return a `Option` taking the following values:
32 /// - `Some(v: Vertex3)` if there is a vertex associated to this ID,
33 /// - `None` otherwise.
34 ///
35 /// # Panics
36 ///
37 /// The method may panic if:
38 /// - the index lands out of bounds,
39 /// - the index cannot be converted to `usize`.
40 #[must_use = "unused return value"]
41 pub fn read_vertex(
42 &self,
43 trans: &mut Transaction,
44 vertex_id: VertexIdType,
45 ) -> StmClosureResult<Option<Vertex3<T>>> {
46 self.vertices.read(trans, vertex_id)
47 }
48
49 #[allow(clippy::missing_errors_doc)]
50 /// Replace the vertex associated to a given identifier and return its old value.
51 ///
52 /// # Arguments
53 ///
54 /// - `vertex_id: VertexIdentifier` -- Identifier of the vertex to replace.
55 /// - `vertex: impl Into<Vertex3>` -- New [`Vertex3`] value.
56 ///
57 /// # Return / Errors
58 ///
59 /// This method is meant to be called in a context where the returned `Result` is used to
60 /// validate the transaction passed as argument. Errors should not be processed manually,
61 /// only processed via the `?` operator.
62 ///
63 /// The result contains an `Option` taking the following values:
64 /// - `Some(v: Vertex3)` if there was an old value,
65 /// - `None` otherwise.
66 ///
67 /// # Panics
68 ///
69 /// The method may panic if:
70 /// - the index lands out of bounds,
71 /// - the index cannot be converted to `usize`.
72 pub fn write_vertex(
73 &self,
74 trans: &mut Transaction,
75 vertex_id: VertexIdType,
76 vertex: impl Into<Vertex3<T>>,
77 ) -> StmClosureResult<Option<Vertex3<T>>> {
78 self.vertices.write(trans, vertex_id, vertex.into())
79 }
80
81 #[allow(clippy::missing_errors_doc)]
82 /// Remove the vertex associated to a given identifier and return it.
83 ///
84 /// # Return / Errors
85 ///
86 /// This method is meant to be called in a context where the returned `Result` is used to
87 /// validate the transaction passed as argument. Errors should not be processed manually,
88 /// only processed via the `?` operator.
89 ///
90 /// The result contains an `Option` taking the following values:
91 /// - `Some(v: Vertex3)` if there was a value,
92 /// - `None` otherwise.
93 ///
94 /// # Panics
95 ///
96 /// The method may panic if:
97 /// - the index lands out of bounds,
98 /// - the index cannot be converted to `usize`.
99 pub fn remove_vertex(
100 &self,
101 trans: &mut Transaction,
102 vertex_id: VertexIdType,
103 ) -> StmClosureResult<Option<Vertex3<T>>> {
104 self.vertices.remove(trans, vertex_id)
105 }
106
107 /// Read the vertex associated to a given identifier.
108 ///
109 /// This variant is equivalent to `read_vertex`, but internally uses a transaction that will be
110 /// retried until validated.
111 #[must_use = "unused return value"]
112 pub fn force_read_vertex(&self, vertex_id: VertexIdType) -> Option<Vertex3<T>> {
113 atomically(|t| self.vertices.read(t, vertex_id))
114 }
115
116 /// Write a vertex to a given identifier, and return its old value.
117 ///
118 /// This variant is equivalent to `write_vertex`, but internally uses a transaction that will be
119 /// retried until validated.
120 pub fn force_write_vertex(
121 &self,
122 vertex_id: VertexIdType,
123 vertex: impl Into<Vertex3<T>>,
124 ) -> Option<Vertex3<T>> {
125 let tmp = vertex.into();
126 atomically(|t| self.vertices.write(t, vertex_id, tmp))
127 }
128
129 #[allow(clippy::must_use_candidate)]
130 /// Remove the vertex associated to a given identifier and return it.
131 ///
132 /// This variant is equivalent to `remove_vertex`, but internally uses a transaction that will
133 /// be retried until validated.
134 pub fn force_remove_vertex(&self, vertex_id: VertexIdType) -> Option<Vertex3<T>> {
135 atomically(|t| self.vertices.remove(t, vertex_id))
136 }
137}
138
139/// ## **Generic attribute-related methods**
140impl<T: CoordsFloat> CMap3<T> {
141 #[allow(clippy::missing_errors_doc)]
142 /// Return the attribute `A` value associated to a given identifier.
143 ///
144 /// The kind of cell `A` binds to is automatically deduced using its `AttributeBind`
145 /// implementation.
146 ///
147 /// # Return / Errors
148 ///
149 /// This method is meant to be called in a context where the returned `Result` is used to
150 /// validate the transaction passed as argument. Errors should not be processed manually,
151 /// only processed via the `?` operator.
152 ///
153 /// This method return a `Option` taking the following values:
154 /// - `Some(a: A)` if there is a value associated to this ID,
155 /// - `None` otherwise, or if there is no storage for this kind of attribute in the map.
156 ///
157 /// # Panics
158 ///
159 /// The method may panic if:
160 /// - the index lands out of bounds,
161 /// - the index cannot be converted to `usize`.
162 pub fn read_attribute<A: AttributeBind + AttributeUpdate>(
163 &self,
164 trans: &mut Transaction,
165 id: A::IdentifierType,
166 ) -> StmClosureResult<Option<A>> {
167 self.attributes.read_attribute::<A>(trans, id)
168 }
169
170 #[allow(clippy::missing_errors_doc)]
171 /// Replace the attribute `A` value associated to a given identifier and return its old value.
172 ///
173 /// # Arguments
174 ///
175 /// - `id: A::IdentifierType` -- Identifier of the cell's value to replace.
176 /// - `val: A` -- Attribute value.
177 ///
178 /// # Return / Errors
179 ///
180 /// This method is meant to be called in a context where the returned `Result` is used to
181 /// validate the transaction passed as argument. Errors should not be processed manually,
182 /// only processed via the `?` operator.
183 ///
184 /// The result contains an `Option` taking the following values:
185 /// - `Some(a: A)` if there was an old value,
186 /// - `None` otherwise, or if there is no storage for this kind of attribute in the map.
187 ///
188 /// # Panics
189 ///
190 /// The method may panic if:
191 /// - the index lands out of bounds,
192 /// - the index cannot be converted to `usize`.
193 pub fn write_attribute<A: AttributeBind + AttributeUpdate>(
194 &self,
195 trans: &mut Transaction,
196 id: A::IdentifierType,
197 val: A,
198 ) -> StmClosureResult<Option<A>> {
199 self.attributes.write_attribute::<A>(trans, id, val)
200 }
201
202 #[allow(clippy::missing_errors_doc)]
203 /// Remove the attribute `A` value associated to a given identifier and return it.
204 ///
205 /// # Return / Errors
206 ///
207 /// This method is meant to be called in a context where the returned `Result` is used to
208 /// validate the transaction passed as argument. Errors should not be processed manually,
209 /// only processed via the `?` operator.
210 ///
211 /// The result contains an `Option` taking the following values:
212 /// - `Some(a: A)` if there was a value,
213 /// - `None` otherwise, or if there is no storage for this kind of attribute in the map.
214 ///
215 /// # Panics
216 ///
217 /// The method may panic if:
218 /// - the index lands out of bounds,
219 /// - the index cannot be converted to `usize`.
220 pub fn remove_attribute<A: AttributeBind + AttributeUpdate>(
221 &self,
222 trans: &mut Transaction,
223 id: A::IdentifierType,
224 ) -> StmClosureResult<Option<A>> {
225 self.attributes.remove_attribute::<A>(trans, id)
226 }
227
228 /// Return the attribute `A` value associated to a given identifier.
229 ///
230 /// This variant is equivalent to `read_attribute`, but internally uses a transaction that will be
231 /// retried until validated.
232 #[allow(clippy::needless_pass_by_value)]
233 pub fn force_read_attribute<A: AttributeBind + AttributeUpdate>(
234 &self,
235 id: A::IdentifierType,
236 ) -> Option<A> {
237 atomically(|t| self.attributes.read_attribute::<A>(t, id.clone()))
238 }
239
240 /// Replace the attribute `A` value associated to a given identifier and return its old value.
241 ///
242 /// This variant is equivalent to `write_attribute`, but internally uses a transaction that will be
243 /// retried until validated.
244 #[allow(clippy::needless_pass_by_value)]
245 pub fn force_write_attribute<A: AttributeBind + AttributeUpdate>(
246 &self,
247 id: A::IdentifierType,
248 val: A,
249 ) -> Option<A> {
250 atomically(|t| self.attributes.write_attribute::<A>(t, id.clone(), val))
251 }
252
253 /// Remove the attribute `A` value associated to a given identifier and return it.
254 ///
255 /// This variant is equivalent to `remove_attribute`, but internally uses a transaction that
256 /// will be retried until validated.
257 #[allow(clippy::needless_pass_by_value)]
258 pub fn force_remove_attribute<A: AttributeBind + AttributeUpdate>(
259 &self,
260 id: A::IdentifierType,
261 ) -> Option<A> {
262 atomically(|t| self.attributes.remove_attribute::<A>(t, id.clone()))
263 }
264 // --- big guns
265
266 /// Remove the attribute `A`'s storage from the map.
267 ///
268 /// This method is useful when implementing routines that use attributes to run; Those can
269 /// then be removed before the final result is returned.
270 pub fn remove_attribute_storage<A: AttributeBind + AttributeUpdate>(&mut self) {
271 self.attributes.remove_storage::<A>();
272 }
273}