1use std::io::BufRead;
8
9pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::Result<usize> {
13 let mut read = 0;
14 loop {
15 let (done, used) = {
16 let available = match r.fill_buf() {
17 Ok(n) => n,
18 Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
19
20 Err(e) => return Err(e),
21 };
22 match memchr::memchr(b'\n', available) {
23 Some(i) => {
24 let end = i + 1;
25 buf.extend_from_slice(&available[..end]);
26 (true, end)
27 }
28 None => match memchr::memchr(b'\r', available) {
29 Some(i) => {
30 let end = i + 1;
31 buf.extend_from_slice(&available[..end]);
32 (true, end)
33 }
34 None => {
35 buf.extend_from_slice(available);
36 (false, available.len())
37 }
38 },
39 }
40 };
41 r.consume(used);
42 read += used;
43 if done || used == 0 {
44 return Ok(read);
45 }
46 }
47}