1use std::ops::{Range, RangeInclusive};
2
3use super::{Pattern, PatternIter};
4
5impl Iterator for PatternIter {
6 type Item = String;
7
8 fn next(&mut self) -> Option<Self::Item> {
9 match self {
10 Self::Range(range) => Some(range.next()?.to_string()),
11 Self::MRange(range) => Some(range.next()?.to_string()),
12 Self::Empty(b) => {
13 if *b {
14 None
15 } else {
16 *b = true;
17 Some(String::new())
18 }
19 }
20 Self::Group(patterns, iterators, last) => {
21 assert_eq!(patterns.len(), iterators.len());
22 assert_eq!(iterators.len(), last.len());
23 let range = Range {
24 start: 0,
25 end: iterators.len(),
26 };
27 let mut next = true;
28 let mut result = String::new();
29 for i in range.into_iter().rev() {
30 if last[i].is_none() || next {
31 let mut next_val = iterators[i].next();
32 if i == 0 && next_val.is_none() {
33 return None; }
35 if next_val.is_none() {
36 iterators[i] = patterns[i].iter();
37 next_val = iterators[i].next();
38 last[i] = next_val;
39 } else {
40 next = false;
41 last[i] = next_val;
42 }
43 }
44 if last[i].is_none() {
46 return None;
47 }
48 let res = last[i].as_ref().unwrap();
49 result.insert_str(0, res.as_str());
50 }
51 Some(result)
52 }
53 Self::Length(iteratrs) => loop {
54 if iteratrs.is_empty() {
55 return None;
56 }
57 let next = iteratrs[0].next();
58 if next.is_none() {
59 iteratrs.remove(0);
60 continue;
61 }
62 return next;
63 },
64 }
65 }
66}
67
68impl Pattern {
69 pub fn iter(&self) -> PatternIter {
70 match &self {
71 Self::Range(range) => PatternIter::Range(range.iter()),
72 Self::MRange(range) => PatternIter::MRange(range.iter()),
73 Self::Group(patterns) => PatternIter::Group(
74 patterns.clone(),
75 patterns.iter().map(Pattern::iter).collect(),
76 patterns.iter().map(|_| None).collect(),
77 ),
78 Self::Length(pattern, range) => {
79 let patterns: Vec<PatternIter> = range
80 .clone()
81 .into_iter()
82 .map(|i| {
83 if i == 0 {
84 return Self::Empty().into_iter();
85 }
86 let patterns: Vec<Self> = RangeInclusive::new(1, i)
87 .map(|_| *pattern.clone())
88 .collect();
89 Self::Group(patterns).into_iter()
90 })
91 .collect();
92 PatternIter::Length(patterns)
93 }
94 Self::Empty() => PatternIter::Empty(false),
95 }
96 }
97}
98
99impl IntoIterator for Pattern {
100 type Item = String;
101
102 type IntoIter = PatternIter;
103
104 fn into_iter(self) -> Self::IntoIter {
105 self.iter()
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use crate::ops::BruteRange;
112
113 use super::*;
114 use nonempty::{nonempty, NonEmpty};
115
116 #[test]
117 fn test_group() {
118 let pattern = Pattern::Group(vec![
119 Pattern::Range(BruteRange::from_range('a'..='b')),
120 Pattern::Range(BruteRange::from_range('a'..='c')),
121 ]);
122 let result: Vec<String> = pattern.iter().collect();
123 assert_eq!(result, vec!["aa", "ab", "ac", "ba", "bb", "bc"]);
124 }
125
126 #[test]
127 fn test_lenght() {
128 let pattern = Pattern::Length(
129 Box::new(Pattern::Range(BruteRange::from_range('a'..='c'))),
130 1..=2,
131 );
132 let result: Vec<String> = pattern.iter().collect();
133 assert_eq!(
134 result,
135 vec!["a", "b", "c", "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc"]
136 );
137 }
138
139 #[test]
140 fn test_lenght2() {
141 let pattern = Pattern::Length(
142 Box::new(Pattern::Range(BruteRange::from_range('a'..='c'))),
143 0..=3,
144 );
145 let result: Vec<String> = pattern.iter().collect();
146 assert_eq!(
147 result,
148 vec![
149 "", "a", "b", "c", "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc", "aaa",
150 "aab", "aac", "aba", "abb", "abc", "aca", "acb", "acc", "baa", "bab", "bac", "bba",
151 "bbb", "bbc", "bca", "bcb", "bcc", "caa", "cab", "cac", "cba", "cbb", "cbc", "cca",
152 "ccb", "ccc"
153 ]
154 );
155 }
156}