fj_core/algorithms/approx/
tolerance.rs

1//! Tolerance value for approximation
2//!
3//! See [`Tolerance`].
4
5use fj_math::Scalar;
6
7/// A tolerance value
8///
9/// A tolerance value is used during approximation. It defines the maximum
10/// allowed deviation of the approximation from the actual shape.
11///
12/// The `Tolerance` type enforces that the tolerance value is always larger than
13/// zero, which is an attribute that the approximation code relies on.
14///
15/// # Failing [`From`]/[`Into`] implementation
16///
17/// The [`From`]/[`Into`] implementations of tolerance are fallible, which goes
18/// against the explicit mandate of those traits, as stated in their
19/// documentation.
20///
21/// A fallible [`Into`] provides a lot of convenience in test code. Since said
22/// documentation doesn't provide any actual reasoning for this requirement, I'm
23/// feeling free to just ignore it.
24#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
25pub struct Tolerance(Scalar);
26
27impl Tolerance {
28    /// Construct a `Tolerance` from a [`Scalar`]
29    ///
30    /// Returns an error, if the passed scalar is not larger than zero.
31    pub fn from_scalar(
32        scalar: impl Into<Scalar>,
33    ) -> Result<Self, InvalidTolerance> {
34        let scalar = scalar.into();
35
36        if scalar <= Scalar::ZERO {
37            return Err(InvalidTolerance(scalar));
38        }
39
40        Ok(Self(scalar))
41    }
42
43    /// Return the [`Scalar`] that defines the tolerance
44    pub fn inner(&self) -> Scalar {
45        self.0
46    }
47}
48
49impl<S> From<S> for Tolerance
50where
51    S: Into<Scalar>,
52{
53    fn from(scalar: S) -> Self {
54        Self::from_scalar(scalar)
55            .expect("Tried to create `Tolerance` from invalid value")
56    }
57}
58
59/// Error converting scalar to tolerance
60#[derive(Debug, thiserror::Error)]
61#[error("Invalid tolerance ({0}); must be above zero")]
62pub struct InvalidTolerance(Scalar);