1use std::io::Read;
27
28pub struct ReadWith<F, S>
30 where F: FnMut() -> Option<S>,
31 S: AsRef<[u8]> + Default
32{
33 f: F,
34 current: S,
35 offset: usize,
36 end: bool
37}
38
39impl<F, S> ReadWith<F, S>
40 where F: FnMut() -> Option<S>,
41 S: AsRef<[u8]> + Default
42{
43 pub fn new(f: F) -> Self
49 {
50 ReadWith
51 {
52 f: f,
53 current: Default::default(),
54 offset: 0,
55 end: false,
56 }
57 }
58}
59
60impl<F,S> Read for ReadWith<F, S>
61 where F: FnMut() -> Option<S>,
62 S: AsRef<[u8]> + Default
63{
64 fn read(&mut self, buf: &mut [u8])
65 -> std::io::Result<usize>
66 {
67 let mut wrote = 0;
68 while !self.end && wrote < buf.len()
69 {
70 let count = (buf.len()-wrote).min(self.current.as_ref().len()-self.offset);
71 buf[wrote..wrote+count]
72 .copy_from_slice( &self.current.as_ref()[self.offset..self.offset+count] );
73 wrote += count;
74 self.offset += count;
75 if self.offset == self.current.as_ref().len()
76 {
77 self.offset = 0;
78 let n = (self.f)();
79 if let Some(n) = n
80 { self.current = n; }
81 else
82 { self.end = true; }
83 }
84 }
85
86 Ok(wrote)
87 }
88}
89
90
91#[cfg(test)]
92mod tests
93{
94 use ::ReadWith;
95
96 #[test]
97 fn references()
98 {
99 let mut output = vec!();
100 let many_strings = ["one", "two", "three"];
101 let mut pos = 0;
102
103 ::std::io::copy(
104 &mut ReadWith::new(
105 ||
106 {
107 if pos == many_strings.len() { return None; }
108 let o = many_strings[pos];
109 pos+=1;
110 Some(o)
111 }
112 ),
113 &mut output,
114 ).unwrap();
115 assert_eq!("onetwothree", ::std::str::from_utf8(&output).unwrap());
116 }
117
118 #[test]
119 fn strings()
120 {
121 let mut output = vec!();
122 let many_strings = ["one", "two", "three"];
123 let mut pos = 0;
124 ::std::io::copy(
125 &mut ReadWith::new(
126 ||
127 {
128 if pos == many_strings.len() { return None; }
129 let o = many_strings[pos];
130 pos+=1;
131 Some(o.to_string() + "\n")
132 }
133 ),
134 &mut output,
135 ).unwrap();
136 assert_eq!("one\ntwo\nthree\n", ::std::str::from_utf8(&output).unwrap());
137 }
138}