letter_sequence/
sequence.rs1pub mod builder;
2pub mod combined;
3pub mod helper;
4pub mod renderer;
5
6pub use element::Element;
7
8use std::convert::Into;
9
10use super::*;
11use crate::sequence::renderer::*;
12use std::fmt;
13
14use std::ops::{AddAssign, SubAssign};
15
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct Sequence {
18 start: u64,
21 end: Option<u64>,
22 inner: Option<u64>,
23 step: u32,
24 initialized: bool,
26 done: bool,
28 renderer: SeqRenderer,
29}
30
31impl Default for Sequence {
32 fn default() -> Self {
33 Self {
34 initialized: false,
35 start: 0,
36 end: None,
37 inner: None,
38 done: false,
39 renderer: Default::default(),
40 step: 1,
41 }
42 }
43}
44
45impl Iterator for Sequence {
46 type Item = Element;
47
48 fn next(&mut self) -> Option<Self::Item> {
49 match (self.done, self.initialized, self.inner) {
50 (true, _, _) => None,
51 (false, false, Some(_)) => {
52 self.initialized = true;
53 Some(self.generate_element())
54 }
55 (false, _, None) => {
56 self.initialized = true;
57 match self.inner(self.start) {
58 Ok(_) => Some(self.generate_element()),
59 _ => None
60 }
61 },
62 (false, true, Some(_)) => {
63 match self.add(self.step as u64) {
64 Ok(_) => Some(self.generate_element()),
65 Err(_) => { self.done = true; None }
66 }
67 }
68 }
69 }
70}
71
72impl fmt::Display for Sequence {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
74 write!(f, "{}", 42 ) }
76}
77
78impl Sequence {
81 fn new_unchecked(inner: u64) -> Self {
84 Self {
85 start: inner,
86 ..Self::default()
87 }
88 }
89
90 pub fn reset(&mut self) {
92 self.inner = None;
93 self.done = false;
94 }
95
96 pub fn zero(&mut self) {
97 self.initialized = false;
98 self.inner = Some(0);
99 self.done = false;
100 }
101
102 pub fn rollover(&mut self) {
103 self.initialized = true;
104 self.inner = Some(0);
105 self.done = false;
106 }
107
108 pub fn add(&mut self, rhs: u64) -> Result<(), SequenceError> {
110 match (self.done, self.inner) {
111 (true, _) => Err(SequenceError::Done),
112 (false, None) => Err(SequenceError::Uninitialized),
113 (false, Some(inner)) => match inner.checked_add(rhs) {
114 None => return Err(SequenceError::OutOfRange),
115 Some(new_inner) => self.inner(new_inner)
116 }
117 }
118 }
119
120 pub fn sub(&mut self, rhs: u64) -> Result<(), SequenceError> {
122 match (self.done, self.inner) {
123 (true, _) => Err(SequenceError::Done),
124 (false, None) => Err(SequenceError::Uninitialized),
125 (false, Some(inner)) => match inner.checked_sub(rhs) {
126 None => return Err(SequenceError::OutOfRange),
127 Some(new_inner) => self.inner(new_inner)
128 }
129 }
130 }
131
132 pub fn set(&mut self, inner: u64) -> Option<Element> {
133 self.initialized = false;
134 self.inner(inner).map( |_| self.generate_element()).ok()
135 }
136
137 fn inner(&mut self, new_inner: u64) -> Result<(), SequenceError> {
138 if let Some(renderlimit) = self.renderer.max() {
140 if renderlimit < new_inner {
141 return Err(SequenceError::OutOfRangeRender);
142 }
143 }
144 if let Some(end) = self.end {
146 if end <= new_inner {
147 return Err(SequenceError::OutOfRange);
148 }
149 }
150 self.inner = Some(new_inner);
151 Ok(())
152 }
153
154 fn generate_element(&self) -> Element {
155 element::ElementBuilder::default()
156 .inner(self.inner.unwrap())
157 .renderer(self.renderer.clone())
158 .build()
159 .unwrap()
160 }
161}
162
163impl<T: Into<u64>> AddAssign<T> for Sequence {
164 fn add_assign(&mut self, rhs: T) {
165 self.initialized = false;
166 self.add(rhs.into()).expect("Failed to call add_assisgn on sequence");
167 }
168}
169
170impl<T: Into<u64>> SubAssign<T> for Sequence {
171 fn sub_assign(&mut self, rhs: T) {
172 self.initialized = false;
173 self.sub(rhs.into()).expect("Failed to call sub_assign on sequence");
174 }
175}
176
177#[cfg(test)]
178mod test {
179 use super::*;
180
181 #[test]
182 fn default() {
183 let mut seq = Sequence::default();
184 let elem = seq.next().unwrap();
185 assert_eq!(elem.to_string(), "0");
186 }
187
188 #[test]
189 fn new_unchecked() {
190 let mut seq = Sequence::new_unchecked(u64::MAX);
191 let elem = seq.next().unwrap();
192 assert_eq!(
193 elem.to_string(),
194 u64::MAX.to_string()
195 );
196 }
197
198 #[test]
199 fn num() {
200 for i in 0..123_456 {
201 let mut seq = SequenceBuilder::new().start(i).build().unwrap();
202 let elem = seq.next().unwrap();
203 assert_eq!(elem.to_string(), i.to_string());
204 }
205 }
206
207 #[test]
208 fn lower() {
209 for i in 0..100 {
210 let mut seq = SequenceBuilder::new().start(i).lower().build().unwrap();
211 let elem = seq.next().unwrap();
212 assert_eq!(
213 elem.to_string().matches(|c: char| !c.is_lowercase()).count(),
214 0
215 );
216 assert_eq!(seq.to_string(), seq.to_string().to_ascii_lowercase(),)
217 }
218 }
219
220 #[test]
221 fn upper() {
222 for i in 0..100 {
223 let mut seq = SequenceBuilder::new().start(i).upper().build().unwrap();
224 let elem = seq.next().unwrap();
225 assert_eq!(
226 elem.to_string().matches(|c: char| !c.is_uppercase()).count(),
227 0
228 );
229 assert_eq!(seq.to_string(), seq.to_string().to_ascii_uppercase(),)
230 }
231 }
232
233 #[test]
235 fn rollover() {
236 use std::convert::TryFrom;
237 let mut seq = SequenceBuilder::try_from("Z").unwrap().build().unwrap();
238 let elem = seq.next().unwrap();
239 assert_eq!(elem.to_string(), "Z");
240 let elem = seq.next().unwrap();
241 assert_eq!(elem.to_string(), "AA");
242 let elem = seq.next().unwrap();
243 assert_eq!(elem.to_string(), "AB");
244
245 let mut seq = SequenceBuilder::try_from("z").unwrap().build().unwrap();
246 let elem = seq.next().unwrap();
247 assert_eq!(elem.to_string(), "z");
248 let elem = seq.next().unwrap();
249 assert_eq!(elem.to_string(), "aa");
250 let elem = seq.next().unwrap();
251 assert_eq!(elem.to_string(), "ab");
252
253 let mut seq = SequenceBuilder::try_from("9").unwrap().build().unwrap();
254 let elem = seq.next().unwrap();
255 assert_eq!(elem.to_string(), (9).to_string());
256 let elem = seq.next().unwrap();
257 assert_eq!(elem.to_string(), (10).to_string());
258 let elem = seq.next().unwrap();
259 assert_eq!(elem.to_string(), (11).to_string());
260 }
261
262 #[test]
263 fn zero() {
264 use std::convert::TryFrom;
265 let mut seq = SequenceBuilder::try_from(0).unwrap().build().unwrap();
266 let elem = seq.next().unwrap();
267 assert_eq!(elem.to_string(), "0");
268 let elem = seq.next().unwrap();
269 assert_eq!(elem.to_string(), "1");
270 seq.zero();
271 let elem = seq.next().unwrap();
272 assert_eq!(elem.to_string(), "0");
273 }
274
275 #[test]
276 fn assignmod() {
277 let mut seq = SequenceBuilder::new().start(42).build().unwrap();
278
279 let elem = seq.next().unwrap();
280 assert_eq!( elem.to_string(), "42" );
281
282 seq += 0u32;
284 let elem = seq.next().unwrap();
285 assert_eq!( elem.to_string(), "42" );
286
287 seq += 5u32;
288 let elem = seq.next().unwrap();
289 assert_eq!( elem.to_string(), "47" );
290
291 seq -= 5u32;
292 let elem = seq.next().unwrap();
293 assert_eq!( elem.to_string(), "42" );
294 }
295}