spherical_cow/
errors.rs

1//! Handles any errors that could occur during packing.
2
3use std::error::Error;
4use std::fmt;
5
6#[derive(Debug)]
7/// All errors thrown by the library
8pub enum SphericalCowError {
9    /// If a sphere is given a negative radius.
10    NegativeRadius,
11    /// If a cuboid is given a negative half extent.
12    NegativeExtents,
13    /// If a sphere is created but is not confined by the `Container`.
14    /// This happens quite a lot and is generally handled silently. This error
15    /// is only thrown by the `init_spheres` method. Usually this means the geometry
16    /// of the container is perhaps not aligned to the origin, it is scaled too small,
17    /// or the spheres you're attempting to pack are too large.
18    Uncontained,
19    /// We choose a random value from the `set_f` vector. `rand` returns an option and we pop
20    /// the value. If it's `None` this error is thrown. Due to the contstuction of the
21    /// rest of the method, it's safe to say this is unreachable.
22    NoneSetF,
23    /// We choose a random value from the `front` vector. `rand` returns an option and we pop
24    /// the value. If it's `None` this error is thrown. Due to the contstuction of the
25    /// rest of the method, it's safe to say this is unreachable.
26    NoneFront,
27}
28
29impl fmt::Display for SphericalCowError {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        match *self {
32            SphericalCowError::NegativeRadius => write!(f, "Supplied radius is negative."),
33            SphericalCowError::NegativeExtents => write!(f, "A supplied half extent is negative."),
34            SphericalCowError::Uncontained => {
35                write!(f, "Sphere is not contained within bounding geometry.")
36            }
37            SphericalCowError::NoneSetF => {
38                write!(f, "Returned none when choosing value from set f.")
39            }
40            SphericalCowError::NoneFront => {
41                write!(f, "Returned none when choosing value from front.")
42            }
43        }
44    }
45}
46
47impl Error for SphericalCowError {}
48
49#[test]
50fn error_display_negative_radius() {
51    use crate::shapes::Sphere;
52    use nalgebra::Point3;
53
54    let err = Sphere::new(Point3::origin(), -1.).unwrap_err();
55    assert_eq!(format!("{}", err), format!("Supplied radius is negative."));
56}
57
58#[test]
59fn error_display_negative_extent() {
60    use crate::shapes::Cuboid;
61
62    let err = Cuboid::new(1., 1., -1.).unwrap_err();
63    assert_eq!(
64        format!("{}", err),
65        format!("A supplied half extent is negative.")
66    );
67}
68
69#[test]
70fn error_display_containment() {
71    use crate::init_spheres;
72    use crate::shapes::Sphere;
73    use nalgebra::Point3;
74
75    let container = Sphere::new(Point3::origin(), 0.1).unwrap();
76
77    let err = init_spheres(&[10., 15., 20.], &container).unwrap_err();
78    assert_eq!(
79        format!("{}", err),
80        format!("Sphere is not contained within bounding geometry.")
81    );
82}
83
84#[test]
85fn error_display_empty_values() {
86    use crate::shapes::Sphere;
87    use rand::prelude::SliceRandom;
88    use rand::thread_rng;
89
90    let empty_vec: Vec<Sphere> = Vec::new();
91    let mut rng = thread_rng();
92
93    let mut err = empty_vec
94        .choose(&mut rng)
95        .ok_or(SphericalCowError::NoneSetF)
96        .unwrap_err();
97    assert_eq!(
98        format!("{}", err),
99        format!("Returned none when choosing value from set f.")
100    );
101
102    err = empty_vec
103        .choose(&mut rng)
104        .ok_or(SphericalCowError::NoneFront)
105        .unwrap_err();
106    assert_eq!(
107        format!("{}", err),
108        format!("Returned none when choosing value from front.")
109    );
110}