diff --git a/src/version_prefix.rs b/src/version_prefix.rs index f18869f..f63a0dd 100644 --- a/src/version_prefix.rs +++ b/src/version_prefix.rs @@ -38,7 +38,7 @@ where self.0.has_seen_version = true; let mut new_buf = vec![0; buf.len() + 1]; new_buf[0] = self.0.version; - (&mut new_buf[1..]).copy_from_slice(buf); + new_buf[1..].copy_from_slice(buf); self.0.wrapped.write(&new_buf).map(|n| n - 1) } } diff --git a/src/whitespace_remover.rs b/src/whitespace_remover.rs index 2a6282a..0d060ba 100644 --- a/src/whitespace_remover.rs +++ b/src/whitespace_remover.rs @@ -20,10 +20,62 @@ where { fn read(&mut self, buf: &mut [u8]) -> Result { let mut my_buf = vec![0; buf.len()]; - let n = self.inner.read(&mut my_buf)?; - my_buf.truncate(n); - my_buf.retain(|d| !d.is_ascii_whitespace()); - buf[..my_buf.len()].copy_from_slice(&my_buf); - Ok(my_buf.len()) + + loop { + let n = self.inner.read(&mut my_buf)?; + if n == 0 { + // the underlying reader is done + return Ok(0); + } + + my_buf.truncate(n); + my_buf.retain(|d| !d.is_ascii_whitespace()); + + // ensure we got at least a byte to return + if !my_buf.is_empty() { + buf[..my_buf.len()].copy_from_slice(&my_buf); + return Ok(my_buf.len()); + } + + // otherwise reset and reread + my_buf.resize(buf.len(), 0); + } + } +} + +#[cfg(test)] +mod tests { + use std::io::Read; + + #[test] + fn functionality() { + const TEST: &str = " t/prau0INWoWUQ0LgQ\tMUdJRcCetBZP\nAyD+DCpn 01yWZT/LBo3Ogk0INwwuAtKNI "; + + let mut stripped = String::new(); + super::WhitespaceRemover::new(TEST.as_bytes()) + .read_to_string(&mut stripped) + .unwrap(); + + assert_eq!( + stripped, + "t/prau0INWoWUQ0LgQMUdJRcCetBZPAyD+DCpn01yWZT/LBo3Ogk0INwwuAtKNI" + ); + } + + #[test] + fn long_whitespace() { + let mut test_string = "a".to_owned(); + test_string.reserve_exact(161); + for _ in 0..20 { + test_string.push_str(" "); + } + test_string.push('b'); + + let mut stripped = String::new(); + super::WhitespaceRemover::new(test_string.as_bytes()) + .read_to_string(&mut stripped) + .unwrap(); + + assert_eq!(stripped, "ab"); } }