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);