truck_geometry/
errors.rs

1use thiserror::Error;
2
3/// Error handler for [`Error`](./errors/enum.Error.html)
4pub type Result<T> = std::result::Result<T, Error>;
5
6/// Geometrical Errors
7#[derive(Debug, PartialEq, Error)]
8pub enum Error {
9    /// The following operations are failed if the knot vector has zero range.
10    /// * Creating `BSplineCurve` or `BSplineSurface`,
11    /// * Calculating bspline basis functions, or
12    /// * Normalizing the knot vector.
13    /// # Examples
14    /// ```
15    /// use truck_geometry::prelude::*;
16    /// use truck_geometry::errors::Error;
17    /// let mut knot_vec = KnotVec::from(vec![0.0, 0.0, 0.0, 0.0]);
18    /// assert_eq!(knot_vec.try_normalize(), Err(Error::ZeroRange));
19    /// assert_eq!(knot_vec.try_bspline_basis_functions(1, 0.0), Err(Error::ZeroRange));
20    ///
21    /// let ctrl_pts = vec![Vector2::new(0.0, 0.0), Vector2::new(1.0, 1.0)];
22    /// assert!(matches!(BSplineCurve::try_new(knot_vec, ctrl_pts), Err(Error::ZeroRange)));
23    /// ```
24    #[error("This knot vector consists single value.")]
25    ZeroRange,
26    /// Fails concatting two knot vectors if there is a difference between the back knot of
27    /// the former knot vector and the front knot of the latter knot vector.
28    /// # Examples
29    /// ```
30    /// use truck_geometry::prelude::*;
31    /// use truck_geometry::errors::Error;
32    /// let mut knot_vec0 = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
33    /// let knot_vec1 = KnotVec::from(vec![2.0, 2.0, 3.0, 3.0]);
34    /// assert!(matches!(knot_vec0.try_concat(&knot_vec1, 1), Err(Error::DifferentBackFront(1.0, 2.0))));
35    /// ```
36    #[error("Cannot concat two knot vectors whose the back of the first and the front of the second are different.
37the back of the first knot vector: {0}
38the front of the second knot vector: {1}")]
39    DifferentBackFront(f64, f64),
40    /// If the knot vector is not clamped, then one cannot concat the vector with another knot vector.
41    /// # Examples
42    /// ```
43    /// use truck_geometry::prelude::*;
44    /// use truck_geometry::errors::Error;
45    /// let mut knot_vec0 = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
46    /// let knot_vec1 = KnotVec::from(vec![2.0, 2.0, 3.0, 3.0]);
47    /// assert!(matches!(knot_vec0.try_concat(&knot_vec1, 2), Err(Error::NotClampedKnotVector)));
48    /// ```
49    #[error("This knot vector is not clamped.")]
50    NotClampedKnotVector,
51    /// Creating a knot vector by `KnotVec::try_from()` is failed if the given vector is not sorted.
52    /// `<KnotVec as From<Vec<f64>>>::from()` does not panic by this error because sorts the given
53    /// vector before creating the knot vector. So, `KnotVec::try_from()` is more efficient than
54    /// `<KnotVec as From<Vec<f64>>>::from()`.
55    /// # Examples
56    /// ```
57    /// use truck_geometry::prelude::*;
58    /// use truck_geometry::errors::Error;
59    /// use std::convert::*;
60    ///
61    /// assert!(matches!(KnotVec::try_from(vec![1.0, 3.0, 0.0, 2.0]), Err(Error::NotSortedVector)));
62    /// assert_eq!(
63    ///     <KnotVec as From<Vec<f64>>>::from(vec![1.0, 3.0, 0.0, 2.0]),
64    ///     KnotVec::try_from(vec![0.0, 1.0, 2.0, 3.0]).unwrap(),
65    /// );
66    /// ```
67    #[error("This knot vector is not sorted.")]
68    NotSortedVector,
69    /// The given degree is too large to calculate bspline basis functions.
70    /// # Examples
71    /// ```
72    /// use truck_geometry::prelude::*;
73    /// use truck_geometry::errors::Error;
74    ///
75    /// // a knot vector with length = 4.
76    /// let knot_vec = KnotVec::from(vec![0.0, 0.0, 1.0, 1.0]);
77    /// assert!(matches!(
78    ///     knot_vec.try_bspline_basis_functions(5, 0.5),
79    ///     Err(Error::TooLargeDegree(4, 5)),
80    /// ));
81    /// ```
82    #[error(
83        "This knot vector is too short compared to the degree.
84the length of knot_vec: {0}
85the degree: {1}"
86    )]
87    TooLargeDegree(usize, usize),
88    /// The specified knot cannot be removed.
89    /// # Examples
90    /// ```
91    /// use truck_geometry::prelude::*;
92    /// use truck_geometry::errors::Error;
93    /// let knot_vec = KnotVec::bezier_knot(2);
94    /// let ctrl_pts = vec![Vector2::new(-1.0, 1.0), Vector2::new(0.0, -1.0), Vector2::new(1.0, 1.0)];
95    /// let mut bspcurve = BSplineCurve::new(knot_vec, ctrl_pts);
96    /// let org_curve = bspcurve.clone();
97    /// bspcurve.add_knot(0.5).add_knot(0.5).add_knot(0.25).add_knot(0.75);
98    /// assert!(bspcurve.try_remove_knot(3).is_ok());
99    /// assert!(matches!(bspcurve.try_remove_knot(2), Err(Error::CannotRemoveKnot(2))));
100    /// ```
101    #[error("The {0}th knot in this knot vector cannot be removed.")]
102    CannotRemoveKnot(usize),
103    /// Empty vector of points cannot construct B-spline.
104    /// # Examples
105    /// ```
106    /// use truck_geometry::prelude::*;
107    /// use truck_geometry::errors::Error;
108    ///
109    /// let knot_vec = KnotVec::bezier_knot(2);
110    /// let ctrl_pts: Vec<Vector4> = Vec::new();
111    /// assert!(matches!(
112    ///     BSplineCurve::try_new(knot_vec, ctrl_pts),
113    ///     Err(Error::EmptyControlPoints),
114    /// ));
115    /// ```
116    #[error("The control point must not be empty.")]
117    EmptyControlPoints,
118    /// The knot vector of B-spline curves or B-spline surfaces must be longer than the corresponded
119    /// array of control points.
120    /// # Examples
121    /// ```
122    /// use truck_geometry::prelude::*;
123    /// use truck_geometry::errors::Error;
124    /// let knot_vec = KnotVec::from(vec![0.0, 1.0, 2.0]);
125    /// let ctrl_pts = vec![Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0), Vector2::new(0.0, 0.0)];
126    /// assert!(matches!(
127    ///     BSplineCurve::try_new(knot_vec, ctrl_pts),
128    ///     Err(Error::TooShortKnotVector(3, 4)),
129    /// ));
130    /// ```
131    #[error(
132        "The knot vector must be more than the control points.
133the length of knot_vec: {0}
134the number of control points: {1}"
135    )]
136    TooShortKnotVector(usize, usize),
137    /// The length of the given arrays of control points to create a B-spline surface is irregular.
138    /// # Examples
139    /// ```
140    /// use truck_geometry::prelude::*;
141    /// use truck_geometry::errors::Error;
142    /// let knot_vecs = (KnotVec::bezier_knot(2), KnotVec::bezier_knot(2));
143    /// let ctrl_pts = vec![
144    ///     vec![Vector2::new(1.0, 2.0), Vector2::new(1.0, 2.0)], // length = 2
145    ///     vec![Vector2::new(1.0, 2.0)] // length = 1
146    /// ];
147    /// assert!(matches!(
148    ///     BSplineSurface::try_new(knot_vecs, ctrl_pts),
149    ///     Err(Error::IrregularControlPoints),
150    /// ));
151    /// ```
152    #[error("The number of control points is irregular")]
153    IrregularControlPoints,
154    /// The vector of control points and the one of weights have different length.
155    /// # Examples
156    /// ```
157    /// use truck_geometry::prelude::*;
158    /// use truck_geometry::errors::Error;
159    /// let bspcurve = BSplineCurve::new(
160    ///     KnotVec::bezier_knot(2),
161    ///     vec![Point2::new(0.0, 1.0), Point2::new(2.0, 3.0), Point2::new(4.0, 5.0)],
162    /// );
163    /// let weights = vec![1.0, 2.0]; // less than control points
164    ///
165    /// assert!(matches!(
166    ///     NurbsCurve::<Vector3>::try_from_bspline_and_weights(bspcurve, weights),
167    ///     Err(Error::DifferentLength),
168    /// ));
169    /// ```
170    #[error("The vector of control points and the one of weights have different length.")]
171    DifferentLength,
172}
173
174#[test]
175#[rustfmt::skip]
176fn print_messages() {
177    use std::io::Write;
178    let stderr = &mut std::io::stderr();
179    writeln!(stderr, "****** test of the expressions of error messages ******\n").unwrap();
180    writeln!(stderr, "{}\n", Error::ZeroRange).unwrap();
181    writeln!(stderr, "{}\n", Error::DifferentBackFront(0.0, 1.0)).unwrap();
182    writeln!(stderr, "{}\n", Error::NotClampedKnotVector).unwrap();
183    writeln!(stderr, "{}\n", Error::NotSortedVector).unwrap();
184    writeln!(stderr, "{}\n", Error::TooLargeDegree(1, 2)).unwrap();
185    writeln!(stderr, "{}\n", Error::CannotRemoveKnot(7)).unwrap();
186    writeln!(stderr, "{}\n", Error::EmptyControlPoints).unwrap();
187    writeln!(stderr, "{}\n", Error::TooShortKnotVector(1, 2)).unwrap();
188    writeln!(stderr, "{}\n", Error::IrregularControlPoints).unwrap();
189    writeln!(stderr, "*******************************************************").unwrap();
190}