aboutsummaryrefslogtreecommitdiff
path: root/vendor/anstream/src/fmt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/anstream/src/fmt.rs')
-rw-r--r--vendor/anstream/src/fmt.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/vendor/anstream/src/fmt.rs b/vendor/anstream/src/fmt.rs
new file mode 100644
index 0000000..e673c26
--- /dev/null
+++ b/vendor/anstream/src/fmt.rs
@@ -0,0 +1,54 @@
+/// 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)
+ }
+ }
+ }
+}