The loop is needed to handle interrupt errors correctly. Writing it differently has no effect either, that's good I guess
Showing the changes to git-protocol/src (1 of 3 files). Show all
Unified · Split
| @@ -26,8 +26,9 @@ mod read { · 25 unmodified lines | ||
| 26 | 26 | /// start of whatever comes next. |
| 27 | 27 | pub struct Reader<T> { |
| 28 | 28 | pub inner: T, |
| 29 | − buf: Option<Vec<u8>>, | |
| 29 | + buf: Vec<u8>, | |
| 30 | 30 | occupied: Option<std::ops::Range<usize>>, |
| 31 | + is_done: bool, | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | impl<T> Reader<T> |
| @@ -37,14 +38,16 @@ mod read { · 3 unmodified lines | ||
| 37 | 38 | pub fn new(inner: T) -> Self { |
| 38 | 39 | Reader { |
| 39 | 40 | inner, |
| 40 | − buf: Some({ | |
| 41 | + buf: { | |
| 41 | 42 | let mut v = Vec::with_capacity(MAX_LINE_LEN); |
| 42 | 43 | v.resize(MAX_LINE_LEN, 0); |
| 43 | 44 | v |
| 44 | − }), | |
| 45 | + }, | |
| 45 | 46 | occupied: None, |
| 47 | + is_done: false, | |
| 46 | 48 | } |
| 47 | 49 | } |
| 50 | + | |
| 48 | 51 | fn read_line_inner<'a>( |
| 49 | 52 | reader: &mut T, |
| 50 | 53 | occupied: &mut Option<std::ops::Range<usize>>, |
| @@ -60,22 +63,20 @@ mod read { · 9 unmodified lines | ||
| 60 | 63 | } |
| 61 | 64 | |
| 62 | 65 | pub fn read_line(&mut self) -> Option<io::Result<Result<Borrowed, decode::Error>>> { |
| 63 | − match self.buf.as_mut() { | |
| 64 | − Some(buf) => { | |
| 65 | − loop { | |
| 66 | − match Self::read_line_inner(&mut self.inner, &mut self.occupied, buf) { | |
| 67 | − Ok(Ok(line)) if line == Borrowed::Flush => { | |
| 68 | − self.buf = None; | |
| 69 | − return None; | |
| 70 | − } | |
| 71 | − Err(e) if e.kind() == io::ErrorKind::Interrupted => continue, | |
| 72 | − // res => return Some(res), | |
| 73 | − res => unimplemented!("tst"), | |
| 74 | − } | |
| 66 | + if self.is_done { | |
| 67 | + return None; | |
| 68 | + } | |
| 69 | + Some(loop { | |
| 70 | + match Self::read_line_inner(&mut self.inner, &mut self.occupied, &mut self.buf) { | |
| 71 | + Ok(Ok(line)) if line == Borrowed::Flush => { | |
| 72 | + self.is_done = true; | |
| 73 | + return None; | |
| 75 | 74 | } |
| 75 | + Err(e) if e.kind() == io::ErrorKind::Interrupted => continue, | |
| 76 | + res => break res, | |
| 77 | + // res => unimplemented!("tst"), | |
| 76 | 78 | } |
| 77 | − None => None, | |
| 78 | − } | |
| 79 | + }) | |
| 79 | 80 | } |
| 80 | 81 | } |
| 81 | 82 | } |