Skip to content

Commit 333f466

Browse files
bors[bot]jansegre
andauthored
Merge #154
154: Add DoubleEndedIterator impl for gradient::Take r=Ogeon a=jansegre `gradient.take(n).rev()` is now possible, closes #153 Co-authored-by: Jan Segre <jan@segre.in>
2 parents 6e5d99e + 902150c commit 333f466

File tree

1 file changed

+34
-7
lines changed

1 file changed

+34
-7
lines changed

palette/src/gradient.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ impl<C: Mix + Clone> Gradient<C> {
101101
from: min,
102102
diff: max - min,
103103
len: n,
104-
current: 0,
104+
from_head: 0,
105+
from_end: 0,
105106
}
106107
}
107108

@@ -132,29 +133,42 @@ pub struct Take<'a, C: Mix + Clone + 'a> {
132133
from: C::Scalar,
133134
diff: C::Scalar,
134135
len: usize,
135-
current: usize,
136+
from_head: usize,
137+
from_end: usize,
136138
}
137139

138140
impl<'a, C: Mix + Clone> Iterator for Take<'a, C> {
139141
type Item = C;
140142

141143
fn next(&mut self) -> Option<C> {
142-
if self.current < self.len {
143-
let i = self.from + (self.diff / cast(self.len)) * cast(self.current);
144-
self.current += 1;
144+
if self.from_head + self.from_end < self.len {
145+
let i = self.from + (self.diff / cast(self.len)) * cast(self.from_head);
146+
self.from_head += 1;
145147
Some(self.gradient.get(i))
146148
} else {
147149
None
148150
}
149151
}
150152

151153
fn size_hint(&self) -> (usize, Option<usize>) {
152-
(self.len - self.current, Some(self.len - self.current))
154+
(self.len - self.from_head - self.from_end, Some(self.len - self.from_head - self.from_end))
153155
}
154156
}
155157

156158
impl<'a, C: Mix + Clone> ExactSizeIterator for Take<'a, C> {}
157159

160+
impl<'a, C: Mix + Clone> DoubleEndedIterator for Take<'a, C> {
161+
fn next_back(&mut self) -> Option<Self::Item> {
162+
if self.from_head + self.from_end < self.len {
163+
let i = self.from + (self.diff / cast(self.len)) * cast(self.len - self.from_end - 1);
164+
self.from_end += 1;
165+
Some(self.gradient.get(i))
166+
} else {
167+
None
168+
}
169+
}
170+
}
171+
158172
///A slice of a Gradient that limits its domain.
159173
#[derive(Clone, Debug)]
160174
pub struct Slice<'a, C: Mix + Clone + 'a> {
@@ -178,7 +192,8 @@ impl<'a, C: Mix + Clone> Slice<'a, C> {
178192
from: min,
179193
diff: max - min,
180194
len: n,
181-
current: 0,
195+
from_head: 0,
196+
from_end: 0,
182197
}
183198
}
184199

@@ -430,4 +445,16 @@ mod test {
430445
assert_relative_eq!(t1, t2);
431446
}
432447
}
448+
449+
#[test]
450+
fn iter_rev_eq_rev_iter() {
451+
let g = Gradient::new(vec![
452+
LinSrgb::new(1.0, 0.0, 0.0),
453+
LinSrgb::new(0.0, 0.0, 1.0),
454+
]);
455+
456+
let v1: Vec<_> = g.take(10).collect::<Vec<_>>().iter().rev().cloned().collect();
457+
let v2: Vec<_> = g.take(10).rev().collect();
458+
assert_eq!(v1, v2);
459+
}
433460
}

0 commit comments

Comments
 (0)