Skip to content

Commit

Permalink
fix(imap-types): Fix SequenceSetIterNaive
Browse files Browse the repository at this point in the history
See #411
  • Loading branch information
duesee committed Jan 9, 2024
1 parent 032c61e commit cce5ad0
Showing 1 changed file with 32 additions and 4 deletions.
36 changes: 32 additions & 4 deletions imap-types/src/sequence.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
fmt::{Debug, Formatter},
num::NonZeroU32,
ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
str::FromStr,
Expand Down Expand Up @@ -464,13 +465,22 @@ pub enum Strategy {
Naive { largest: NonZeroU32 },
}

#[derive(Debug)]
pub struct SequenceSetIterNaive<'a> {
iter: core::slice::Iter<'a, Sequence>,
active_range: Option<RangeInclusive<u32>>,
active_range: Option<Box<dyn DoubleEndedIterator<Item = u32>>>,
largest: NonZeroU32,
}

impl<'a> Debug for SequenceSetIterNaive<'a> {
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
f.debug_struct("SequenceSetIterNaive")
.field("iter", &self.iter)
.field("active_range", &"<no debug>")
.field("largest", &self.largest)
.finish()
}
}

impl<'a> Iterator for SequenceSetIterNaive<'a> {
type Item = NonZeroU32;

Expand All @@ -492,7 +502,11 @@ impl<'a> Iterator for SequenceSetIterNaive<'a> {
Sequence::Range(from, to) => {
let from = from.expand(self.largest);
let to = to.expand(self.largest);
self.active_range = Some(u32::from(from)..=u32::from(to));
self.active_range = if from <= to {
Some(Box::new(u32::from(from)..=u32::from(to)))
} else {
Some(Box::new((u32::from(to)..=u32::from(from)).rev()))
};
}
},
None => return None,
Expand Down Expand Up @@ -701,7 +715,7 @@ mod tests {
("*", vec![3]),
("1:*", vec![1, 2, 3]),
("5,1:*,2:*", vec![5, 1, 2, 3, 2, 3]),
("*:2", vec![]),
("*:2", vec![3, 2]),
("*:*", vec![3]),
("4:6,*", vec![4, 5, 6, 3]),
]
Expand All @@ -726,4 +740,18 @@ mod tests {
assert_eq!(*expected, got);
}
}

/// See https://github.com/duesee/imap-codec/issues/411
#[test]
fn test_issue_411() {
let seq = SequenceSet::try_from("22,21,22,*:20").unwrap();
let largest = NonZeroU32::new(23).unwrap();

let expected = [22, 21, 22, 23, 22, 21, 20]
.map(|n| NonZeroU32::new(n).unwrap())
.to_vec();
let got: Vec<_> = seq.iter(Strategy::Naive { largest }).collect();

assert_eq!(expected, got);
}
}

0 comments on commit cce5ad0

Please sign in to comment.