use crate::error::{
GraphError, GreeksError, InterpolationError, OperationErrorKind, OptionsError, PositionError,
};
use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub enum SurfaceError {
Point3DError {
reason: &'static str,
},
OperationError(OperationErrorKind),
StdError {
reason: String,
},
ConstructionError(String),
AnalysisError(String),
}
impl SurfaceError {
pub fn operation_not_supported(operation: &str, reason: &str) -> Self {
SurfaceError::OperationError(OperationErrorKind::NotSupported {
operation: operation.to_string(),
reason: reason.to_string(),
})
}
pub fn invalid_parameters(operation: &str, reason: &str) -> Self {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation: operation.to_string(),
reason: reason.to_string(),
})
}
}
impl Error for SurfaceError {}
impl fmt::Display for SurfaceError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SurfaceError::OperationError(err) => write!(f, "Operation error: {err}"),
SurfaceError::StdError { reason } => write!(f, "Error: {reason}"),
SurfaceError::Point3DError { reason } => write!(f, "Error: {reason}"),
SurfaceError::ConstructionError(reason) => write!(f, "Construction error: {reason}"),
SurfaceError::AnalysisError(reason) => write!(f, "Analysis error: {reason}"),
}
}
}
impl From<PositionError> for SurfaceError {
fn from(err: PositionError) -> Self {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation: "Position".to_string(),
reason: err.to_string(),
})
}
}
impl From<InterpolationError> for SurfaceError {
fn from(err: InterpolationError) -> Self {
SurfaceError::StdError {
reason: err.to_string(),
}
}
}
impl From<OptionsError> for SurfaceError {
fn from(err: OptionsError) -> Self {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation: "Option".to_string(),
reason: err.to_string(),
})
}
}
impl From<GreeksError> for SurfaceError {
fn from(err: GreeksError) -> Self {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation: "Greek".to_string(),
reason: err.to_string(),
})
}
}
impl From<Box<dyn Error>> for SurfaceError {
fn from(err: Box<dyn Error>) -> Self {
SurfaceError::StdError {
reason: err.to_string(),
}
}
}
impl From<GraphError> for SurfaceError {
fn from(err: GraphError) -> Self {
SurfaceError::StdError {
reason: err.to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::CurveError;
use crate::error::curves::CurvesResult;
use crate::error::position::PositionValidationErrorKind;
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct TestError {
message: String,
}
impl fmt::Display for TestError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
impl Error for TestError {}
#[test]
fn test_operation_not_supported() {
let error = SurfaceError::operation_not_supported(
"test_operation",
"Operation cannot be performed",
);
match error {
SurfaceError::OperationError(OperationErrorKind::NotSupported {
operation,
reason,
}) => {
assert_eq!(operation, "test_operation");
assert_eq!(reason, "Operation cannot be performed");
}
_ => panic!("Wrong error variant"),
}
}
#[test]
fn test_invalid_parameters() {
let error = SurfaceError::invalid_parameters("test_params", "Invalid input parameters");
match error {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation,
reason,
}) => {
assert_eq!(operation, "test_params");
assert_eq!(reason, "Invalid input parameters");
}
_ => panic!("Wrong error variant"),
}
}
#[test]
fn test_display_operation_error() {
let error = SurfaceError::operation_not_supported(
"test_operation",
"Operation cannot be performed",
);
assert!(error.to_string().contains("Operation error"));
assert!(error.to_string().contains("test_operation"));
assert!(error.to_string().contains("Operation cannot be performed"));
}
#[test]
fn test_display_std_error() {
let error = SurfaceError::StdError {
reason: "Standard error test".to_string(),
};
assert_eq!(error.to_string(), "Error: Standard error test");
}
#[test]
fn test_display_point3d_error() {
let error = SurfaceError::Point3DError {
reason: "Point error test",
};
assert_eq!(error.to_string(), "Error: Point error test");
}
#[test]
fn test_display_construction_error() {
let error = SurfaceError::ConstructionError("Construction failed".to_string());
assert_eq!(error.to_string(), "Construction error: Construction failed");
}
#[test]
fn test_display_analysis_error() {
let error = SurfaceError::AnalysisError("Analysis failed".to_string());
assert_eq!(error.to_string(), "Analysis error: Analysis failed");
}
#[test]
fn test_from_position_error() {
let pos_error =
PositionError::ValidationError(PositionValidationErrorKind::InvalidPosition {
reason: "Test position error".to_string(),
});
let surface_error = SurfaceError::from(pos_error);
match surface_error {
SurfaceError::OperationError(OperationErrorKind::InvalidParameters {
operation,
..
}) => {
assert_eq!(operation, "Position");
}
_ => panic!("Wrong error variant"),
}
}
#[test]
fn test_from_box_dyn_error() {
let test_error = TestError {
message: "Test box error".to_string(),
};
let boxed_error: Box<dyn Error> = Box::new(test_error);
let surface_error = SurfaceError::from(boxed_error);
match surface_error {
SurfaceError::StdError { reason } => {
assert_eq!(reason, "Test box error");
}
_ => panic!("Wrong error variant"),
}
}
#[test]
fn test_curves_result_err() {
let result: CurvesResult<i32> = Err(CurveError::AnalysisError("Test error".to_string()));
assert!(result.is_err());
match result {
Err(err) => {
assert_eq!(err.to_string(), "Analysis error: Test error");
}
Ok(_) => panic!("Expected an error result"),
}
}
#[test]
fn test_curves_result_err_alternative() {
let err = CurveError::AnalysisError("Test error".to_string());
assert_eq!(err.to_string(), "Analysis error: Test error");
let result: CurvesResult<i32> = Err(err);
assert!(result.is_err());
match result {
Err(e) => {
assert_eq!(e.to_string(), "Analysis error: Test error");
}
Ok(_) => panic!("Expected an error result"),
}
}
}