diff --git a/src/sink.rs b/src/sink.rs index dc2f825..ed14d8c 100644 --- a/src/sink.rs +++ b/src/sink.rs @@ -1,4 +1,4 @@ -use core::fmt; +use core::fmt::{self, Arguments}; pub trait StrSink { type Error; @@ -29,17 +29,37 @@ where } } +pub trait FmtSink: StrSink { + fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), ::Error>; +} + +impl FmtSink for W +where + W: fmt::Write, +{ + fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), ::Error> { + self.write_fmt(args) + } +} + +#[macro_export] +macro_rules! sink_fmt { + ($dst:expr, $($arg:tt)*) => { + FmtSink::sink_fmt($dst, core::format_args!($($arg)*)) + }; +} + #[cfg(feature = "alloc")] pub use string_sink::SinkString; #[cfg(feature = "alloc")] mod string_sink { - use core::convert::Infallible; + use core::{convert::Infallible, fmt::{self, Arguments}}; #[cfg(not(feature = "std"))] use alloc::string::String; - use super::StrSink; + use super::{StrSink, FmtSink}; #[repr(transparent)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] @@ -94,4 +114,13 @@ mod string_sink { Ok(()) } } + + impl FmtSink for SinkString { + fn sink_fmt<'a>(&mut self, args: Arguments<'a>) -> Result<(), ::Error> { + // We discard any error, since writing to a `String` should be infallible for correct + // implementations of `Display` etc. + let _ = ::write_fmt(&mut self.0, args); + Ok(()) + } + } }