|
1 | 1 | use crate::config::{Config, View}; |
2 | | -use crate::error::Result; |
| 2 | +use crate::error::{Error, Result}; |
3 | 3 | use crate::models::enums::{NotificationReason, NotificationType}; |
4 | 4 | use crate::models::Notification; |
5 | 5 | use regex::Regex; |
@@ -52,37 +52,41 @@ impl Filter { |
52 | 52 | ) -> Result<Self> { |
53 | 53 | let parsed_types: Vec<NotificationType> = exclude_types |
54 | 54 | .iter() |
55 | | - .filter_map(|s| { |
56 | | - let t: NotificationType = s.parse().ok()?; |
57 | | - if t == NotificationType::Unknown { |
58 | | - None |
| 55 | + .map(|s| { |
| 56 | + let parsed: NotificationType = s.parse().unwrap_or(NotificationType::Unknown); |
| 57 | + if parsed == NotificationType::Unknown { |
| 58 | + Err(Error::Config(format!( |
| 59 | + "Unknown notification type in exclude_types: {s}" |
| 60 | + ))) |
59 | 61 | } else { |
60 | | - Some(t) |
| 62 | + Ok(parsed) |
61 | 63 | } |
62 | 64 | }) |
63 | | - .collect(); |
| 65 | + .collect::<Result<_>>()?; |
64 | 66 |
|
65 | 67 | let parsed_reasons: Vec<NotificationReason> = exclude_reasons |
66 | 68 | .iter() |
67 | | - .filter_map(|s| { |
68 | | - let r: NotificationReason = s.parse().ok()?; |
69 | | - if r == NotificationReason::Unknown { |
70 | | - None |
| 69 | + .map(|s| { |
| 70 | + let parsed: NotificationReason = s.parse().unwrap_or(NotificationReason::Unknown); |
| 71 | + if parsed == NotificationReason::Unknown { |
| 72 | + Err(Error::Config(format!( |
| 73 | + "Unknown notification reason in exclude_reasons: {s}" |
| 74 | + ))) |
71 | 75 | } else { |
72 | | - Some(r) |
| 76 | + Ok(parsed) |
73 | 77 | } |
74 | 78 | }) |
75 | | - .collect(); |
| 79 | + .collect::<Result<_>>()?; |
76 | 80 |
|
77 | 81 | let parsed_repos: Vec<RepoPattern> = exclude_repos |
78 | 82 | .iter() |
79 | | - .filter_map(|s| RepoPattern::new(s).ok()) |
80 | | - .collect(); |
| 83 | + .map(|s| RepoPattern::new(s)) |
| 84 | + .collect::<Result<_>>()?; |
81 | 85 |
|
82 | 86 | let parsed_subjects: Vec<Regex> = exclude_subjects |
83 | 87 | .iter() |
84 | | - .filter_map(|s| Regex::new(&format!("(?i){s}")).ok()) |
85 | | - .collect(); |
| 88 | + .map(|s| Regex::new(&format!("(?i){s}")).map_err(Error::from)) |
| 89 | + .collect::<Result<_>>()?; |
86 | 90 |
|
87 | 91 | let mut patterns = Vec::new(); |
88 | 92 | if let Some(pattern) = pattern { |
@@ -290,18 +294,19 @@ mod tests { |
290 | 294 | } |
291 | 295 |
|
292 | 296 | #[test] |
293 | | - fn test_unrecognised_type_ignored() { |
294 | | - let filter = Filter::new( |
295 | | - None, |
296 | | - &["NonExistentType".to_string(), "Issue".to_string()], |
297 | | - &[], |
298 | | - &[], |
299 | | - &[], |
300 | | - ) |
301 | | - .unwrap(); |
302 | | - // Only Issue should be excluded, unrecognised type silently ignored |
303 | | - assert_eq!(filter.exclude_types.len(), 1); |
304 | | - assert_eq!(filter.exclude_types[0], NotificationType::Issue); |
| 297 | + fn test_unrecognised_type_returns_error() { |
| 298 | + let err = Filter::new(None, &["NonExistentType".to_string()], &[], &[], &[]).unwrap_err(); |
| 299 | + assert!(err |
| 300 | + .to_string() |
| 301 | + .contains("Unknown notification type in exclude_types: NonExistentType")); |
| 302 | + } |
| 303 | + |
| 304 | + #[test] |
| 305 | + fn test_unrecognised_reason_returns_error() { |
| 306 | + let err = Filter::new(None, &[], &["mystery".to_string()], &[], &[]).unwrap_err(); |
| 307 | + assert!(err |
| 308 | + .to_string() |
| 309 | + .contains("Unknown notification reason in exclude_reasons: mystery")); |
305 | 310 | } |
306 | 311 |
|
307 | 312 | #[test] |
@@ -373,4 +378,10 @@ mod tests { |
373 | 378 | assert!(!filter.matches(&lower)); |
374 | 379 | assert!(filter.matches(&normal)); |
375 | 380 | } |
| 381 | + |
| 382 | + #[test] |
| 383 | + fn test_invalid_subject_regex_returns_error() { |
| 384 | + let err = Filter::new(None, &[], &[], &[], &["[".to_string()]).unwrap_err(); |
| 385 | + assert!(err.to_string().contains("Filter error")); |
| 386 | + } |
376 | 387 | } |
0 commit comments