1#[cfg(feature = "layered-io")]
2use layered_io::{ReadLayered, Status};
3use std::io::{self, Read};
4
5pub trait ReadStr: Read {
7 fn read_str(&mut self, buf: &mut str) -> io::Result<usize>;
13
14 #[inline]
16 fn read_exact_str(&mut self, buf: &mut str) -> io::Result<()> {
17 default_read_exact_str(self, buf)
18 }
19}
20
21#[cfg(feature = "layered-io")]
24pub trait ReadStrLayered: ReadLayered + ReadStr {
25 fn read_str_with_status(&mut self, buf: &mut str) -> io::Result<(usize, Status)>;
31
32 #[inline]
37 fn read_exact_str_using_status(&mut self, buf: &mut str) -> io::Result<Status> {
38 default_read_exact_str_using_status(self, buf)
39 }
40}
41
42pub fn default_read_exact_str<Inner: ReadStr + ?Sized>(
44 inner: &mut Inner,
45 mut buf: &mut str,
46) -> io::Result<()> {
47 while !buf.is_empty() {
48 match inner.read_str(buf) {
49 Ok(0) => break,
50 Ok(size) => buf = buf.split_at_mut(size).1,
51 Err(e) => return Err(e),
52 }
53 }
54
55 if buf.is_empty() {
56 Ok(())
57 } else {
58 Err(io::Error::new(
59 io::ErrorKind::UnexpectedEof,
60 "failed to fill whole buffer",
61 ))
62 }
63}
64
65#[cfg(feature = "layered-io")]
67pub fn default_read_exact_str_using_status<Inner: ReadStrLayered + ?Sized>(
68 inner: &mut Inner,
69 mut buf: &mut str,
70) -> io::Result<Status> {
71 let mut result_status = Status::active();
72
73 while !buf.is_empty() {
74 match inner.read_str_with_status(buf) {
75 Ok((size, status)) => {
76 buf = buf.split_at_mut(size).1;
77 if status.is_end() {
78 result_status = status;
79 break;
80 }
81 }
82 Err(e) => return Err(e),
83 }
84 }
85
86 if buf.is_empty() {
87 Ok(result_status)
88 } else {
89 Err(io::Error::new(
90 io::ErrorKind::UnexpectedEof,
91 "failed to fill whole buffer",
92 ))
93 }
94}