1use std::io::ErrorKind;
6
7pub struct TerminateEarlyOnUnexpectedEof<I, T>
14where
15 I: Iterator<Item = Result<T, csv::Error>>,
16{
17 inner: I,
18}
19
20impl<I, T> TerminateEarlyOnUnexpectedEof<I, T>
21where
22 I: Iterator<Item = Result<T, csv::Error>>,
23{
24 pub fn new(inner: I) -> Self {
26 Self { inner }
27 }
28
29 pub fn into_inner(self) -> I {
31 self.inner
32 }
33}
34
35impl<I, T> Iterator for TerminateEarlyOnUnexpectedEof<I, T>
36where
37 I: Iterator<Item = Result<T, csv::Error>>,
38{
39 type Item = Result<T, csv::Error>;
40 fn next(&mut self) -> std::option::Option<<Self as Iterator>::Item> {
41 match self.inner.next() {
42 Some(Ok(item)) => Some(Ok(item)),
43 None => None,
44 Some(Err(e)) => match is_early_eof(&e) {
45 true => None,
46 false => Some(Err(e)),
47 },
48 }
49 }
50}
51
52fn is_early_eof(e: &csv::Error) -> bool {
54 if let csv::ErrorKind::Io(io_err) = e.kind()
55 && let ErrorKind::UnexpectedEof = io_err.kind()
56 {
57 return true;
58 }
59 false
60}
61
62pub trait EarlyEofOk<I, T>
64where
65 I: Iterator<Item = Result<T, csv::Error>>,
66{
67 fn early_eof_ok(self) -> TerminateEarlyOnUnexpectedEof<I, T>;
68}
69
70impl<I, T> EarlyEofOk<I, T> for I
71where
72 I: Iterator<Item = Result<T, csv::Error>>,
73{
74 fn early_eof_ok(self) -> TerminateEarlyOnUnexpectedEof<I, T> {
75 TerminateEarlyOnUnexpectedEof::new(self)
76 }
77}