1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, FgumiError>;
7
8#[derive(Error, Debug)]
10pub enum FgumiError {
11 #[error("Invalid parameter '{parameter}': {reason}")]
13 InvalidParameter {
14 parameter: String,
16 reason: String,
18 },
19
20 #[error("Invalid frequency threshold: {value} (must be between {min} and {max})")]
22 InvalidFrequency {
23 value: f64,
25 min: f64,
27 max: f64,
29 },
30
31 #[error("Invalid quality threshold: {value} (must be between 0 and {max})")]
33 InvalidQuality {
34 value: u8,
36 max: u8,
38 },
39
40 #[error("Invalid {file_type} file '{path}': {reason}")]
42 InvalidFileFormat {
43 file_type: String,
45 path: String,
47 reason: String,
49 },
50
51 #[error("Reference sequence '{ref_name}' not found in header")]
53 ReferenceNotFound {
54 ref_name: String,
56 },
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn test_invalid_parameter() {
65 let error = FgumiError::InvalidParameter {
66 parameter: "min-reads".to_string(),
67 reason: "must be >= 1".to_string(),
68 };
69 let msg = format!("{error}");
70 assert!(msg.contains("Invalid parameter 'min-reads'"));
71 assert!(msg.contains("must be >= 1"));
72 }
73
74 #[test]
75 fn test_invalid_frequency() {
76 let error = FgumiError::InvalidFrequency { value: 1.5, min: 0.0, max: 1.0 };
77 let msg = format!("{error}");
78 assert!(msg.contains("1.5"));
79 assert!(msg.contains("between 0 and 1"));
80 }
81
82 #[test]
83 fn test_invalid_file_format() {
84 let error = FgumiError::InvalidFileFormat {
85 file_type: "BAM".to_string(),
86 path: "/path/to/file.bam".to_string(),
87 reason: "truncated file".to_string(),
88 };
89 let msg = format!("{error}");
90 assert!(msg.contains("Invalid BAM file"));
91 assert!(msg.contains("truncated file"));
92 }
93
94 #[test]
95 fn test_reference_not_found() {
96 let error = FgumiError::ReferenceNotFound { ref_name: "chr1".to_string() };
97 let msg = format!("{error}");
98 assert!(msg.contains("Reference sequence 'chr1' not found"));
99 }
100}