Skip to main content

fgumi_lib/
errors.rs

1//! Custom error types for fgumi operations.
2
3use thiserror::Error;
4
5/// Result type alias for fgumi operations
6pub type Result<T> = std::result::Result<T, FgumiError>;
7
8/// Error type for fgumi operations
9#[derive(Error, Debug)]
10pub enum FgumiError {
11    /// Invalid parameter value provided
12    #[error("Invalid parameter '{parameter}': {reason}")]
13    InvalidParameter {
14        /// The parameter name
15        parameter: String,
16        /// Explanation of why it's invalid
17        reason: String,
18    },
19
20    /// Invalid frequency threshold
21    #[error("Invalid frequency threshold: {value} (must be between {min} and {max})")]
22    InvalidFrequency {
23        /// The invalid frequency value
24        value: f64,
25        /// Minimum valid value
26        min: f64,
27        /// Maximum valid value
28        max: f64,
29    },
30
31    /// Invalid quality threshold
32    #[error("Invalid quality threshold: {value} (must be between 0 and {max})")]
33    InvalidQuality {
34        /// The invalid quality value
35        value: u8,
36        /// Maximum valid value (usually 93 for SAM/BAM)
37        max: u8,
38    },
39
40    /// File format error
41    #[error("Invalid {file_type} file '{path}': {reason}")]
42    InvalidFileFormat {
43        /// Type of file (e.g., "BAM", "FASTQ")
44        file_type: String,
45        /// Path to the file
46        path: String,
47        /// Explanation of the problem
48        reason: String,
49    },
50
51    /// Required reference sequence not found
52    #[error("Reference sequence '{ref_name}' not found in header")]
53    ReferenceNotFound {
54        /// The reference sequence name
55        ref_name: String,
56    },
57
58    /// Invalid memory size string
59    #[error("Invalid memory size: {reason}")]
60    InvalidMemorySize {
61        /// Explanation of why the value is invalid
62        reason: String,
63    },
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_invalid_parameter() {
72        let error = FgumiError::InvalidParameter {
73            parameter: "min-reads".to_string(),
74            reason: "must be >= 1".to_string(),
75        };
76        let msg = format!("{error}");
77        assert!(msg.contains("Invalid parameter 'min-reads'"));
78        assert!(msg.contains("must be >= 1"));
79    }
80
81    #[test]
82    fn test_invalid_frequency() {
83        let error = FgumiError::InvalidFrequency { value: 1.5, min: 0.0, max: 1.0 };
84        let msg = format!("{error}");
85        assert!(msg.contains("1.5"));
86        assert!(msg.contains("between 0 and 1"));
87    }
88
89    #[test]
90    fn test_invalid_file_format() {
91        let error = FgumiError::InvalidFileFormat {
92            file_type: "BAM".to_string(),
93            path: "/path/to/file.bam".to_string(),
94            reason: "truncated file".to_string(),
95        };
96        let msg = format!("{error}");
97        assert!(msg.contains("Invalid BAM file"));
98        assert!(msg.contains("truncated file"));
99    }
100
101    #[test]
102    fn test_invalid_memory_size() {
103        let error =
104            FgumiError::InvalidMemorySize { reason: "Memory size cannot be empty".to_string() };
105        let msg = format!("{error}");
106        assert!(msg.contains("Invalid memory size"));
107        assert!(msg.contains("cannot be empty"));
108    }
109
110    #[test]
111    fn test_reference_not_found() {
112        let error = FgumiError::ReferenceNotFound { ref_name: "chr1".to_string() };
113        let msg = format!("{error}");
114        assert!(msg.contains("Reference sequence 'chr1' not found"));
115    }
116}