Skip to content

Commit 26e0a14

Browse files
committed
updated shuflr example, added negiter and stackoll examples
1 parent 8a8318b commit 26e0a14

File tree

7 files changed

+161
-15
lines changed

7 files changed

+161
-15
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ in a controlled repository now.
3131
* `deref.rs`: deref trait example
3232
* `from.rs`: from / try_from trait example
3333
* `prog.rs`, `prog2.rs`: state machine examples using closures
34-
* `shuflr/`: iterator implementation example
34+
* `negiter/`: example iterator adapter
35+
* `stackcoll/`: example fromiterator implementation
36+
* `shuflr/`: example iterator implementation

clean.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ do
55
done
66
for i in */Cargo.toml
77
do
8-
( cd `dirname $i` && cargo clean -q )
8+
( cd `dirname $i` && cargo clean -q && rm -rf .git )
99
done

negiter/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "negiter"
3+
version = "0.1.0"
4+
authors = ["Bart Massey <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
11+
[lib]
12+
name = "negiter"
13+
path = "negiter.rs"

negiter/negiter.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
pub struct IterNegate<I, T>
2+
where
3+
I: Iterator<Item = T>,
4+
T: std::ops::Neg<Output = T>,
5+
{
6+
iter: I,
7+
}
8+
9+
impl<I, T> Iterator for IterNegate<I, T>
10+
where
11+
I: Iterator<Item = T>,
12+
T: std::ops::Neg<Output = T>,
13+
{
14+
type Item = T;
15+
16+
fn next(&mut self) -> Option<Self::Item> {
17+
self.iter.next().map(|v| -v)
18+
}
19+
}
20+
21+
impl<I, T> IterNegate<I, T>
22+
where
23+
I: Iterator<Item = T>,
24+
T: std::ops::Neg<Output = T>,
25+
{
26+
pub fn negated(iter: I) -> Self {
27+
Self { iter }
28+
}
29+
}
30+
31+
pub trait IterNegateExt<I, T>
32+
where
33+
I: Iterator<Item = T>,
34+
T: std::ops::Neg<Output = T>,
35+
{
36+
fn negated(self) -> IterNegate<I, T>;
37+
}
38+
39+
impl<I, T> IterNegateExt<I, T> for I
40+
where
41+
I: Iterator<Item = T>,
42+
T: std::ops::Neg<Output = T>,
43+
{
44+
fn negated(self) -> IterNegate<I, T> {
45+
IterNegate::negated(self)
46+
}
47+
}
48+
49+
#[test]
50+
fn test_negated_example() {
51+
let numbers: Vec<i32> = (0..=5).collect();
52+
let negs: Vec<i32> = numbers.iter().cloned().negated().collect();
53+
assert_eq!(numbers.len(), negs.len());
54+
for (i, &v) in numbers.iter().enumerate() {
55+
assert_eq!(-v, negs[i]);
56+
}
57+
}

shuflr/shuflr.rs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub struct IterShuffled<'a, T> {
77
}
88

99
impl<'a, T> IterShuffled<'a, T> {
10-
pub fn new<R>(values: &'a [T], rng: &mut R) -> Self
10+
pub fn shuffled<R>(values: &'a [T], rng: &mut R) -> Self
1111
where
1212
R: Rng + ?Sized,
1313
{
@@ -25,29 +25,68 @@ impl<'a, T> Iterator for IterShuffled<'a, T> {
2525
}
2626
}
2727

28-
pub trait Shuffled<T> {
28+
pub trait ShuffledExt<T> {
2929
fn shuffled<R>(&self, rng: &mut R) -> IterShuffled<T>
3030
where
3131
R: Rng + ?Sized;
3232
}
3333

34-
impl<T> Shuffled<T> for [T] {
34+
impl<T> ShuffledExt<T> for [T] {
3535
fn shuffled<R>(&self, rng: &mut R) -> IterShuffled<T>
3636
where
3737
R: Rng + ?Sized,
3838
{
39-
IterShuffled::new(self, rng)
39+
IterShuffled::shuffled(self, rng)
4040
}
4141
}
4242

43-
#[test]
44-
pub fn test_shuffled() {
45-
let mut rng = rand::thread_rng();
46-
let vals = &['a', 'b', 'c'];
47-
let mut v = Vec::new();
48-
for &c in vals.shuffled(&mut rng) {
49-
v.push(c);
43+
#[cfg(test)]
44+
mod tests {
45+
use rand::RngCore;
46+
47+
use super::*;
48+
49+
#[test]
50+
pub fn test_shuffled_works() {
51+
let mut rng = rand::thread_rng();
52+
let vals = &['a', 'b', 'c'];
53+
let mut v = Vec::new();
54+
for &c in vals.shuffled(&mut rng) {
55+
v.push(c);
56+
}
57+
v.sort();
58+
assert_eq!(&v, vals);
59+
}
60+
61+
struct FakeRng(u64);
62+
63+
impl RngCore for FakeRng {
64+
fn next_u32(&mut self) -> u32 {
65+
let result = self.0 as u32;
66+
self.0 += 1;
67+
result
68+
}
69+
fn next_u64(&mut self) -> u64 {
70+
let result = self.0;
71+
self.0 += 1;
72+
result
73+
}
74+
fn fill_bytes(&mut self, _dest: &mut [u8]) {
75+
panic!("fill_bytes")
76+
}
77+
fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), rand::Error> {
78+
panic!("try_fill_bytes")
79+
}
80+
}
81+
82+
#[test]
83+
pub fn test_shuffled_shuffles() {
84+
let mut rng = FakeRng(0);
85+
let vals = &['a', 'b', 'c'];
86+
let mut v = Vec::new();
87+
for &c in vals.shuffled(&mut rng) {
88+
v.push(c);
89+
}
90+
assert_eq!(&v, &['a', 'c', 'b']);
5091
}
51-
v.sort();
52-
assert_eq!(&v, vals);
5392
}

stackcoll/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "stackcoll"
3+
version = "0.1.0"
4+
authors = ["Bart Massey <[email protected]>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
11+
[lib]
12+
name = "stackcoll"
13+
path = "stackcoll.rs"

stackcoll/stackcoll.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
pub struct Stack<T>(Vec<T>);
2+
3+
impl<T> std::iter::FromIterator<T> for Stack<T> {
4+
fn from_iter<I>(ii: I) -> Self
5+
where
6+
I: IntoIterator<Item = T>
7+
{
8+
let iter = ii.into_iter();
9+
let mut stack = Vec::with_capacity(iter.size_hint().1.unwrap_or(0));
10+
for v in iter {
11+
stack.push(v);
12+
}
13+
Stack(stack)
14+
}
15+
}
16+
17+
#[test]
18+
fn test_stack_collect() {
19+
let s: Stack<u8> = (0..7).collect();
20+
let v: Vec<u8> = (0..7).collect();
21+
assert_eq!(&s.0, &v);
22+
}

0 commit comments

Comments
 (0)