1use std::fmt::{self, Arguments};
2use std::io::{self, Write};
3
4pub trait WriteStr: Write {
6 #[inline]
9 fn write_str(&mut self, buf: &str) -> io::Result<()> {
10 default_write_str(self, buf)
11 }
12}
13
14#[inline]
17pub fn default_write_str<Inner: Write + ?Sized>(inner: &mut Inner, buf: &str) -> io::Result<()> {
18 inner.write_all(buf.as_bytes())
20}
21
22pub fn default_write_fmt<Inner: WriteStr + ?Sized>(
25 inner: &mut Inner,
26 fmt: Arguments,
27) -> io::Result<()> {
28 struct Adaptor<'a, Inner: ?Sized + 'a> {
29 inner: &'a mut Inner,
30 error: Option<io::Error>,
31 }
32
33 impl<Inner: WriteStr + ?Sized> fmt::Write for Adaptor<'_, Inner> {
34 fn write_str(&mut self, s: &str) -> fmt::Result {
35 match self.inner.write_str(s) {
36 Ok(()) => Ok(()),
37 Err(e) => {
38 self.error = Some(e);
39 Err(fmt::Error)
40 }
41 }
42 }
43 }
44
45 let mut adapter = Adaptor { inner, error: None };
46 match fmt::write(&mut adapter, fmt) {
47 Ok(()) => Ok(()),
48 Err(_) => Err(adapter
49 .error
50 .unwrap_or_else(|| io::Error::new(io::ErrorKind::Other, "formatter error"))),
51 }
52}