更具体地说,我正在采用标准,过滤掉某些行,.lines().filter_map()
并且我想将其结果与csv::Reader
.
标准库提供了std::io::Cursor
将缓冲区与缓冲区中的位置包装在一起的类型。这可以用来进一步简化Veedrac 的答案中给出的代码:
use std::io::{self, Cursor, Read};
struct IteratorAsRead<I>
where
I: Iterator,
{
iter: I,
cursor: Option<Cursor<I::Item>>,
}
impl<I> IteratorAsRead<I>
where
I: Iterator,
{
pub fn new<T>(iter: T) -> Self
where
T: IntoIterator<IntoIter = I, Item = I::Item>,
{
let mut iter = iter.into_iter();
let cursor = iter.next().map(Cursor::new);
IteratorAsRead { iter, cursor }
}
}
impl<I> Read for IteratorAsRead<I>
where
I: Iterator,
Cursor<I::Item>: Read,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
while let Some(ref mut cursor) = self.cursor {
let read = cursor.read(buf)?;
if read > 0 {
return Ok(read);
}
self.cursor = self.iter.next().map(Cursor::new);
}
Ok(0)
}
}
#[test]
fn small_pieces_are_combined() {
let iterable = ["h", "e", "l", "l", "o"];
let mut reader = IteratorAsRead::new(&iterable);
let mut buf = vec![];
let bytes = reader.read_to_end(&mut buf).unwrap();
assert_eq!(&buf[..bytes], b"hello");
}
#[test]
fn partial_reads() {
let iterable = ["hello"];
let mut reader = IteratorAsRead::new(&iterable);
let mut buf = [0; 2];
let bytes = reader.read(&mut buf).unwrap();
assert_eq!(&buf[..bytes], b"he");
let bytes = reader.read(&mut buf).unwrap();
assert_eq!(&buf[..bytes], b"ll");
let bytes = reader.read(&mut buf).unwrap();
assert_eq!(&buf[..bytes], b"o");
}
Run Code Online (Sandbox Code Playgroud)