io.rs 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! IO helpers.
  5. use std::io::BufRead;
  6. /// Read all bytes until a newline (the `0xA` byte) or a carriage return (`\r`) is reached, and append them to the provided buffer.
  7. ///
  8. /// Adapted from <https://doc.rust-lang.org/std/io/trait.BufRead.html#method.read_line>.
  9. pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::Result<usize> {
  10. let mut read = 0;
  11. loop {
  12. let (done, used) = {
  13. let available = match r.fill_buf() {
  14. Ok(n) => n,
  15. Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
  16. Err(e) => return Err(e),
  17. };
  18. match memchr::memchr(b'\n', available) {
  19. Some(i) => {
  20. let end = i + 1;
  21. buf.extend_from_slice(&available[..end]);
  22. (true, end)
  23. }
  24. None => match memchr::memchr(b'\r', available) {
  25. Some(i) => {
  26. let end = i + 1;
  27. buf.extend_from_slice(&available[..end]);
  28. (true, end)
  29. }
  30. None => {
  31. buf.extend_from_slice(available);
  32. (false, available.len())
  33. }
  34. },
  35. }
  36. };
  37. r.consume(used);
  38. read += used;
  39. if done || used == 0 {
  40. return Ok(read);
  41. }
  42. }
  43. }