edgeparse_core/utils/
page_range.rs1use std::collections::HashSet;
7
8pub fn parse_page_range(range_str: &str, total_pages: usize) -> Option<HashSet<usize>> {
18 let trimmed = range_str.trim();
19 if trimmed.is_empty() {
20 return None;
21 }
22
23 let mut pages = HashSet::new();
24 for part in trimmed.split(',') {
25 let part = part.trim();
26 if part.is_empty() {
27 continue;
28 }
29 if let Some((start_str, end_str)) = part.split_once('-') {
30 let start: usize = start_str.trim().parse().ok()?;
31 let end: usize = end_str.trim().parse().ok()?;
32 if start == 0 || end == 0 || start > end {
33 return None;
34 }
35 for p in start..=end.min(total_pages) {
36 pages.insert(p);
37 }
38 } else {
39 let p: usize = part.parse().ok()?;
40 if p == 0 {
41 return None;
42 }
43 if p <= total_pages {
44 pages.insert(p);
45 }
46 }
47 }
48
49 if pages.is_empty() {
50 None
51 } else {
52 Some(pages)
53 }
54}
55
56pub fn filter_pages<T>(pages: Vec<Vec<T>>, selected: &HashSet<usize>) -> Vec<Vec<T>> {
60 pages
61 .into_iter()
62 .enumerate()
63 .filter_map(|(i, page)| {
64 let page_num = i + 1; if selected.contains(&page_num) {
66 Some(page)
67 } else {
68 None
69 }
70 })
71 .collect()
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_parse_single_page() {
80 let result = parse_page_range("3", 10).unwrap();
81 assert_eq!(result, HashSet::from([3]));
82 }
83
84 #[test]
85 fn test_parse_range() {
86 let result = parse_page_range("2-5", 10).unwrap();
87 assert_eq!(result, HashSet::from([2, 3, 4, 5]));
88 }
89
90 #[test]
91 fn test_parse_mixed() {
92 let result = parse_page_range("1-3,7,10-12", 15).unwrap();
93 assert_eq!(result, HashSet::from([1, 2, 3, 7, 10, 11, 12]));
94 }
95
96 #[test]
97 fn test_parse_empty() {
98 assert!(parse_page_range("", 10).is_none());
99 }
100
101 #[test]
102 fn test_parse_beyond_total() {
103 let result = parse_page_range("1-5", 3).unwrap();
104 assert_eq!(result, HashSet::from([1, 2, 3]));
105 }
106
107 #[test]
108 fn test_filter_pages() {
109 let pages = vec![vec![1], vec![2], vec![3], vec![4], vec![5]];
110 let selected = HashSet::from([1, 3, 5]);
111 let filtered = filter_pages(pages, &selected);
112 assert_eq!(filtered, vec![vec![1], vec![3], vec![5]]);
113 }
114}