Skip to content

Commit 6ff37b3

Browse files
authored
refactor!: update various return types for better consistency (#67)
* refactor: change Vector2::normal_dir return type to a result it is a propagation of the internal unit_dir return * refactor: change CMap2::vertex return type also clarify documentation of vertex & insert_vertex methods * refactor: change CMap2::vertex return type to a result * fix: update cmap2 test code * fix: update render code * fix: finish tests updates * fix: update benchmarks code * chore: add comments to justify the new unwraps * refactor: remove the dead / unused code mention around beta render * doc: fix duplicated line * chore: correct inconsistent & wrong doc * chore: update changelog with last PRs' content
1 parent a928c30 commit 6ff37b3

File tree

10 files changed

+119
-62
lines changed

10 files changed

+119
-62
lines changed

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,22 @@
44

55
## To be released
66

7-
...
7+
### Workspace
8+
9+
- implement nighly conditional compilation for doc generation (#66)
10+
11+
### Refactor
12+
13+
#### honeycomb-core
14+
15+
<sup>core definitions and tools for combinatorial map implementation</sup>
16+
17+
- change some main methods return type to have better overall consistency (#67):
18+
- `Vector2::normal_dir` now returns a result instead of potentially panicking
19+
- `CMap2::vertex` now returns a result instead of panicking if no associated vertex is found
20+
- remove deprecated items from the last release (#64):
21+
- `AttrSparseVec::get_mut`, `AttrCompactVec::get_mut`
22+
- `utils::square_cmap2`, `utils::splitsquare_cmap2`
823

924
---
1025

honeycomb-benches/benches/splitsquaremap/shift.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ fn offset(mut map: CMap2<FloatType>, offsets: &[Vector2<FloatType>]) {
3232
let n_offsets = offsets.len();
3333
let vertices = map.fetch_vertices();
3434
vertices.identifiers.iter().for_each(|vertex_id| {
35-
let current_value = map.vertex(*vertex_id as DartIdentifier);
35+
// we can unwrap this safely since we built the grid manually
36+
// & know that vertices are correctly defined
37+
let current_value = map.vertex(*vertex_id as DartIdentifier).unwrap();
3638
let _ = map.replace_vertex(
3739
*vertex_id as VertexIdentifier,
3840
current_value + offsets[*vertex_id as usize % n_offsets],
@@ -56,7 +58,9 @@ fn offset_if_inner(mut map: CMap2<FloatType>, offsets: &[Vector2<FloatType>]) {
5658
}
5759
});
5860
inner.iter().for_each(|vertex_id| {
59-
let current_value = map.vertex(*vertex_id);
61+
// we can unwrap this safely since we built the grid manually
62+
// & know that vertices are correctly defined
63+
let current_value = map.vertex(*vertex_id).unwrap();
6064
let _ = map.replace_vertex(
6165
*vertex_id,
6266
current_value + offsets[*vertex_id as usize % n_offsets],

honeycomb-benches/benches/squaremap/shift.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ fn offset(mut map: CMap2<FloatType>, offsets: &[Vector2<FloatType>]) {
3232
let n_offsets = offsets.len();
3333
let vertices = map.fetch_vertices();
3434
vertices.identifiers.iter().for_each(|vertex_id| {
35-
let current_value = map.vertex(*vertex_id as DartIdentifier);
35+
// we can unwrap this safely since we built the grid manually
36+
// & know that vertices are correctly defined
37+
let current_value = map.vertex(*vertex_id as DartIdentifier).unwrap();
3638
let _ = map.replace_vertex(
3739
*vertex_id,
3840
current_value + offsets[*vertex_id as usize % n_offsets],
@@ -56,7 +58,9 @@ fn offset_if_inner(mut map: CMap2<FloatType>, offsets: &[Vector2<FloatType>]) {
5658
}
5759
});
5860
inner.iter().for_each(|vertex_id| {
59-
let current_value = map.vertex(*vertex_id);
61+
// we can unwrap this safely since we built the grid manually
62+
// & know that vertices are correctly defined
63+
let current_value = map.vertex(*vertex_id).unwrap();
6064
let _ = map.replace_vertex(
6165
*vertex_id,
6266
current_value + offsets[*vertex_id as usize % n_offsets],

honeycomb-core/src/cmap2/embed.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,30 @@ impl<T: CoordsFloat> CMap2<T> {
1818
self.vertices.n_attributes()
1919
}
2020

21+
#[allow(clippy::missing_errors_doc)]
2122
/// Fetch vertex value associated to a given identifier.
2223
///
2324
/// # Arguments
2425
///
2526
/// - `vertex_id: VertexIdentifier` -- Identifier of the given vertex.
2627
///
27-
/// # Return
28+
/// # Return / Errors
2829
///
29-
/// Return a reference to the [Vertex2] associated to the ID.
30+
/// This method return a `Result` taking the following values:
31+
/// - `Ok(v: Vertex2)` if there is a vertex associated to this ID.
32+
/// - `Err(CMapError::UndefinedVertexID)` -- otherwise
3033
///
3134
/// # Panics
3235
///
33-
/// The method may panic if no vertex is associated to the specified index, or the ID lands
34-
/// out of bounds.
36+
/// The method may panic if:
37+
/// - the index lands out of bounds
38+
/// - the index cannot be converted to `usize`
3539
///
36-
#[must_use = "returned value is not used, consider removing this method call"]
37-
pub fn vertex(&self, vertex_id: VertexIdentifier) -> Vertex2<T> {
38-
self.vertices.get(&vertex_id).unwrap()
40+
pub fn vertex(&self, vertex_id: VertexIdentifier) -> Result<Vertex2<T>, CMapError> {
41+
if let Some(val) = self.vertices.get(&vertex_id) {
42+
return Ok(*val);
43+
}
44+
Err(CMapError::UndefinedVertex)
3945
}
4046

4147
/// Insert a vertex in the combinatorial map.
@@ -49,9 +55,12 @@ impl<T: CoordsFloat> CMap2<T> {
4955
/// - `vertex_id: VertexIdentifier` -- Vertex identifier to attribute a value to.
5056
/// - `vertex: impl Into<Vertex2>` -- Value used to create a [Vertex2] value.
5157
///
52-
/// # Return
58+
/// # Panics
5359
///
54-
/// Return an option which may contain the previous value associated to the specified vertex ID.
60+
/// The method may panic if:
61+
/// - **there is already a vertex associated to the specified index**
62+
/// - the index lands out of bounds
63+
/// - the index cannot be converted to `usize`
5564
///
5665
pub fn insert_vertex(&mut self, vertex_id: VertexIdentifier, vertex: impl Into<Vertex2<T>>) {
5766
self.vertices.insert(&vertex_id, vertex.into());

honeycomb-core/src/cmap2/structure.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ use std::collections::BTreeSet;
133133
/// assert_eq!(&faces.identifiers, &[1]);
134134
/// // we can check the vertices
135135
/// let vertices = map.fetch_vertices();
136-
/// let mut value_iterator = vertices.identifiers.iter().map(|vertex_id| map.vertex(*vertex_id));
136+
/// let mut value_iterator = vertices.identifiers.iter().map(|vertex_id| map.vertex(*vertex_id).unwrap());
137137
/// assert_eq!(value_iterator.next(), Some(Vertex2::from((0.0, 0.0)))); // vertex ID 1
138138
/// assert_eq!(value_iterator.next(), Some(Vertex2::from((0.0, 1.0)))); // vertex ID 3
139139
/// assert_eq!(value_iterator.next(), Some(Vertex2::from((1.0, 0.0)))); // vertex ID 5

honeycomb-core/src/cmap2/tests.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ fn example_test() {
5050
assert_eq!(map.beta::<2>(2), 4);
5151
assert_eq!(map.vertex_id(2), 2);
5252
assert_eq!(map.vertex_id(5), 2);
53-
assert_eq!(map.vertex(2), Vertex2::from((1.5, 0.0)));
53+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((1.5, 0.0)));
5454
assert_eq!(map.vertex_id(3), 3);
5555
assert_eq!(map.vertex_id(4), 3);
56-
assert_eq!(map.vertex(3), Vertex2::from((0.0, 1.5)));
56+
assert_eq!(map.vertex(3).unwrap(), Vertex2::from((0.0, 1.5)));
5757
let edges = map.fetch_edges();
5858
assert_eq!(&edges.identifiers, &[1, 2, 3, 5, 6]);
5959

@@ -62,12 +62,12 @@ fn example_test() {
6262
map.replace_vertex(2, Vertex2::from((1.0, 0.0))),
6363
Ok(Vertex2::from((1.5, 0.0)))
6464
);
65-
assert_eq!(map.vertex(2), Vertex2::from((1.0, 0.0)));
65+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((1.0, 0.0)));
6666
assert_eq!(
6767
map.replace_vertex(3, Vertex2::from((0.0, 1.0))),
6868
Ok(Vertex2::from((0.0, 1.5)))
6969
);
70-
assert_eq!(map.vertex(3), Vertex2::from((0.0, 1.0)));
70+
assert_eq!(map.vertex(3).unwrap(), Vertex2::from((0.0, 1.0)));
7171

7272
// separate the diagonal from the rest
7373
map.one_unsew(1);
@@ -89,10 +89,10 @@ fn example_test() {
8989
assert_eq!(&edges.identifiers, &[1, 3, 5, 6]);
9090
let vertices = map.fetch_vertices();
9191
assert_eq!(&vertices.identifiers, &[1, 3, 5, 6]);
92-
assert_eq!(map.vertex(1), Vertex2::from((0.0, 0.0)));
93-
assert_eq!(map.vertex(5), Vertex2::from((1.0, 0.0)));
94-
assert_eq!(map.vertex(6), Vertex2::from((1.0, 1.0)));
95-
assert_eq!(map.vertex(3), Vertex2::from((0.0, 1.0)));
92+
assert_eq!(map.vertex(1).unwrap(), Vertex2::from((0.0, 0.0)));
93+
assert_eq!(map.vertex(5).unwrap(), Vertex2::from((1.0, 0.0)));
94+
assert_eq!(map.vertex(6).unwrap(), Vertex2::from((1.0, 1.0)));
95+
assert_eq!(map.vertex(3).unwrap(), Vertex2::from((0.0, 1.0)));
9696
// darts
9797
assert_eq!(map.n_unused_darts(), 2); // there are unused darts since we removed the diagonal
9898
assert_eq!(map.beta_runtime(1, 1), 5);
@@ -134,8 +134,8 @@ fn two_sew_complete() {
134134
map.insert_vertex(3, (1.0, 1.0));
135135
map.insert_vertex(4, (1.0, 0.0));
136136
map.two_sew(1, 3);
137-
assert_eq!(map.vertex(1), Vertex2::from((0.5, 0.0)));
138-
assert_eq!(map.vertex(2), Vertex2::from((0.5, 1.0)));
137+
assert_eq!(map.vertex(1).unwrap(), Vertex2::from((0.5, 0.0)));
138+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.5, 1.0)));
139139
}
140140

141141
#[test]
@@ -147,15 +147,15 @@ fn two_sew_incomplete() {
147147
map.insert_vertex(3, (1.0, 1.0));
148148
map.two_sew(1, 3);
149149
// missing beta1 image for dart 3
150-
assert_eq!(map.vertex(1), Vertex2::from((0.0, 0.0)));
151-
assert_eq!(map.vertex(2), Vertex2::from((0.5, 1.0)));
150+
assert_eq!(map.vertex(1).unwrap(), Vertex2::from((0.0, 0.0)));
151+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.5, 1.0)));
152152
map.two_unsew(1);
153153
assert_eq!(map.add_free_dart(), 4);
154154
map.one_link(3, 4);
155155
map.two_sew(1, 3);
156156
// missing vertex for dart 4
157-
assert_eq!(map.vertex(1), Vertex2::from((0.0, 0.0)));
158-
assert_eq!(map.vertex(2), Vertex2::from((0.5, 1.0)));
157+
assert_eq!(map.vertex(1).unwrap(), Vertex2::from((0.0, 0.0)));
158+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.5, 1.0)));
159159
}
160160

161161
#[test]
@@ -164,8 +164,8 @@ fn two_sew_no_b1() {
164164
map.insert_vertex(1, (0.0, 0.0));
165165
map.insert_vertex(2, (1.0, 1.0));
166166
map.two_sew(1, 2);
167-
assert_eq!(map.vertex(1), Vertex2::from((0.0, 0.0)));
168-
assert_eq!(map.vertex(2), Vertex2::from((1.0, 1.0)));
167+
assert_eq!(map.vertex(1).unwrap(), Vertex2::from((0.0, 0.0)));
168+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((1.0, 1.0)));
169169
}
170170

171171
#[test]
@@ -207,7 +207,7 @@ fn one_sew_complete() {
207207
map.insert_vertex(2, (0.0, 1.0));
208208
map.insert_vertex(3, (0.0, 2.0));
209209
map.one_sew(1, 3);
210-
assert_eq!(map.vertex(2), Vertex2::from((0.0, 1.5)));
210+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.0, 1.5)));
211211
}
212212

213213
#[test]
@@ -217,7 +217,7 @@ fn one_sew_incomplete_attributes() {
217217
map.insert_vertex(1, (0.0, 0.0));
218218
map.insert_vertex(2, (0.0, 1.0));
219219
map.one_sew(1, 3);
220-
assert_eq!(map.vertex(2), Vertex2::from((0.0, 1.0)));
220+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.0, 1.0)));
221221
}
222222

223223
#[test]
@@ -226,7 +226,7 @@ fn one_sew_incomplete_beta() {
226226
map.insert_vertex(1, (0.0, 0.0));
227227
map.insert_vertex(2, (0.0, 1.0));
228228
map.one_sew(1, 2);
229-
assert_eq!(map.vertex(2), Vertex2::from((0.0, 1.0)));
229+
assert_eq!(map.vertex(2).unwrap(), Vertex2::from((0.0, 1.0)));
230230
}
231231
#[test]
232232
#[should_panic(expected = "No vertex defined on dart 2, use `one_link` instead of `one_sew`")]

honeycomb-core/src/spatial_repr/coords.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use std::ops::{
1818
// ------ CONTENT
1919

2020
/// Coordinates-level error enum
21-
#[derive(Debug)]
21+
#[derive(Debug, PartialEq)]
2222
pub enum CoordsError {
2323
/// Error during the computation of the unit directional vector.
2424
///

honeycomb-core/src/spatial_repr/vector.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{Coords2, CoordsError, CoordsFloat};
2929
/// let unit_y = Vector2::unit_y();
3030
///
3131
/// assert_eq!(unit_x.dot(&unit_y), 0.0);
32-
/// assert_eq!(unit_x.normal_dir(), unit_y);
32+
/// assert_eq!(unit_x.normal_dir().unwrap(), unit_y);
3333
///
3434
/// let two: FloatType = 2.0;
3535
/// let x_plus_y: Vector2<FloatType> = unit_x + unit_y;
@@ -127,14 +127,14 @@ impl<T: CoordsFloat> Vector2<T> {
127127
///
128128
/// # Errors
129129
///
130-
/// This method will panic if called on a `Vector2` with a norm equal to zero, i.e. a null
131-
/// `Vector2`.
130+
/// This method will return an error if called on a `Vector2` with a norm equal to zero,
131+
/// i.e. a null `Vector2`.
132132
///
133133
/// # Example
134134
///
135135
/// See [Vector2] example.
136136
///
137-
pub fn unit_dir(&self) -> Result<Vector2<T>, CoordsError> {
137+
pub fn unit_dir(&self) -> Result<Self, CoordsError> {
138138
let norm = self.norm();
139139
if norm.is_zero() {
140140
Err(CoordsError::InvalidUnitDir)
@@ -150,25 +150,23 @@ impl<T: CoordsFloat> Vector2<T> {
150150
/// Return a [Vector2] indicating the direction of the normal to `self`. The norm of the
151151
/// returned struct is equal to one.
152152
///
153-
/// # Panics
153+
/// # Errors
154154
///
155-
/// Because the returned `Vector2` is normalized, this method may panic under the same
156-
/// condition as [`Self::unit_dir`].
155+
/// This method will return an error if called on a `Vector2` with a norm equal to zero,
156+
/// i.e. a null `Vector2`.
157157
///
158158
/// # Example
159159
///
160160
/// See [Vector2] example.
161161
///
162-
#[must_use = "constructed object is not used, consider removing this method call"]
163-
pub fn normal_dir(&self) -> Self {
162+
pub fn normal_dir(&self) -> Result<Vector2<T>, CoordsError> {
164163
Self {
165164
inner: Coords2 {
166165
x: -self.inner.y,
167166
y: self.inner.x,
168167
},
169168
}
170169
.unit_dir()
171-
.unwrap()
172170
}
173171

174172
/// Compute the dot product between two vectors
@@ -342,22 +340,28 @@ mod tests {
342340
fn normal_dir() {
343341
let along_x = Vector2::unit_x() * 4.0;
344342
let along_y = Vector2::unit_y() * 3.0;
345-
assert!(almost_equal_vec(&along_x.normal_dir(), &Vector2::unit_y()));
346343
assert!(almost_equal_vec(
347-
&Vector2::unit_x().normal_dir(),
344+
&along_x.normal_dir().unwrap(),
345+
&Vector2::unit_y()
346+
));
347+
assert!(almost_equal_vec(
348+
&Vector2::unit_x().normal_dir().unwrap(),
348349
&Vector2::unit_y()
349350
));
350-
assert!(almost_equal_vec(&along_y.normal_dir(), &-Vector2::unit_x()));
351351
assert!(almost_equal_vec(
352-
&Vector2::unit_y().normal_dir(),
352+
&along_y.normal_dir().unwrap(),
353+
&-Vector2::unit_x()
354+
));
355+
assert!(almost_equal_vec(
356+
&Vector2::unit_y().normal_dir().unwrap(),
353357
&-Vector2::unit_x()
354358
));
355359
}
356360

357361
#[test]
358-
#[should_panic(expected = "called `Result::unwrap()` on an `Err` value: InvalidUnitDir")]
359362
fn normal_dir_of_null_vel() {
360363
let origin: Vector2<FloatType> = Vector2::default();
361-
let _ = origin.normal_dir(); // panics
364+
let err = origin.normal_dir();
365+
assert_eq!(err, Err(CoordsError::InvalidUnitDir));
362366
}
363367
}

honeycomb-examples/examples/render/squaremap_shift.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ fn main() {
4848
.map(|d_id| map.beta::<2>(d_id))
4949
.collect();
5050
if !neighbors_vertex_cell.contains(&NULL_DART_ID) {
51-
let current_value = map.vertex(*vertex_id);
51+
// we can unwrap this safely since we built the grid manually
52+
// & know that vertices are correctly defined
53+
let current_value = map.vertex(*vertex_id).unwrap();
5254
let _ = map.replace_vertex(
5355
*vertex_id,
5456
current_value + offsets[*vertex_id as usize % n_offsets],

0 commit comments

Comments
 (0)