55 lines
1.4 KiB
Rust
55 lines
1.4 KiB
Rust
/// A shim which allows a [`std::io::Write`] to be implemented in terms of a [`std::fmt::Write`]
|
|
///
|
|
/// This saves off I/O errors. instead of discarding them
|
|
pub(crate) struct Adapter<W>
|
|
where
|
|
W: FnMut(&[u8]) -> std::io::Result<()>,
|
|
{
|
|
writer: W,
|
|
error: std::io::Result<()>,
|
|
}
|
|
|
|
impl<W> Adapter<W>
|
|
where
|
|
W: FnMut(&[u8]) -> std::io::Result<()>,
|
|
{
|
|
pub(crate) fn new(writer: W) -> Self {
|
|
Adapter {
|
|
writer,
|
|
error: Ok(()),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn write_fmt(mut self, fmt: std::fmt::Arguments<'_>) -> std::io::Result<()> {
|
|
match std::fmt::write(&mut self, fmt) {
|
|
Ok(()) => Ok(()),
|
|
Err(..) => {
|
|
// check if the error came from the underlying `Write` or not
|
|
if self.error.is_err() {
|
|
self.error
|
|
} else {
|
|
Err(std::io::Error::new(
|
|
std::io::ErrorKind::Other,
|
|
"formatter error",
|
|
))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<W> std::fmt::Write for Adapter<W>
|
|
where
|
|
W: FnMut(&[u8]) -> std::io::Result<()>,
|
|
{
|
|
fn write_str(&mut self, s: &str) -> std::fmt::Result {
|
|
match (self.writer)(s.as_bytes()) {
|
|
Ok(()) => Ok(()),
|
|
Err(e) => {
|
|
self.error = Err(e);
|
|
Err(std::fmt::Error)
|
|
}
|
|
}
|
|
}
|
|
}
|