1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, Error>;
7
8pub(crate) fn check_range(name: &str, value: f64, min: f64, max: f64) -> Result<()> {
11 if value >= min && value <= max {
12 Ok(())
13 } else {
14 Err(Error::ConfigError(format!(
15 "{name} must be in [{min}, {max}], got {value}"
16 )))
17 }
18}
19
20pub(crate) fn check_at_least(name: &str, value: f64, min: f64) -> Result<()> {
22 if value.is_finite() && value >= min {
23 Ok(())
24 } else {
25 Err(Error::ConfigError(format!(
26 "{name} must be a finite number >= {min}, got {value}"
27 )))
28 }
29}
30
31#[derive(Debug, Error)]
33pub enum Error {
34 #[error("Invalid geometry: {0}")]
36 InvalidGeometry(String),
37
38 #[error("Invalid boundary: {0}")]
40 InvalidBoundary(String),
41
42 #[error("Configuration error: {0}")]
44 ConfigError(String),
45
46 #[error("NFP computation failed: {0}")]
48 NfpError(String),
49
50 #[error("No valid placement found for geometry: {0}")]
52 NoPlacement(String),
53
54 #[error("Computation cancelled")]
56 Cancelled,
57
58 #[error("Timeout exceeded after {0}ms")]
60 Timeout(u64),
61
62 #[cfg(feature = "serde")]
64 #[error("Serialization error: {0}")]
65 SerializationError(String),
66
67 #[error("Internal error: {0}")]
69 Internal(String),
70}