use core::fmt;
use writeable::{Writeable, adapters::Concat, adapters::Replace};
pub(crate) trait WriteableExt {
fn replace_streaming<S, W1>(self, needle: S, replacement: W1) -> Replace<Self, S, W1>
where
Self: Sized;
fn concat_streaming<W1>(self, other: W1) -> Concat<Self, W1>
where
Self: Sized;
fn into_write_fn<W1: fmt::Write>(self) -> impl FnMut(&mut W1) -> fmt::Result;
}
impl<W> WriteableExt for W
where
W: Writeable,
{
#[inline]
fn replace_streaming<S, W1>(self, needle: S, replacement: W1) -> Replace<Self, S, W1> {
Replace {
source: self,
needle,
replacement,
}
}
#[inline]
fn concat_streaming<W1>(self, other: W1) -> Concat<Self, W1> {
Concat(self, other)
}
#[inline]
fn into_write_fn<W1: fmt::Write>(self) -> impl FnMut(&mut W1) -> fmt::Result {
move |sink| self.write_to(sink)
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_replace_streaming() {
use super::WriteableExt;
use writeable::assert_writeable_eq;
assert_writeable_eq!(
"Hello, World!".replace_streaming("World", "Earth"),
"Hello, Earth!",
);
}
#[test]
fn test_concat_streaming() {
use super::WriteableExt;
use writeable::assert_writeable_eq;
assert_writeable_eq!(
"Hello, ".concat_streaming("Earth").concat_streaming('!'),
"Hello, Earth!",
);
}
#[test]
fn test_third_party_fn() {
use super::WriteableExt;
use core::fmt;
struct ThirdPartySink(String);
impl fmt::Write for ThirdPartySink {
fn write_str(&mut self, value: &str) -> fmt::Result {
self.0.write_str(value)
}
}
fn third_party_fn(
value: impl FnOnce(&mut ThirdPartySink) -> fmt::Result,
) -> Result<String, fmt::Error> {
let mut sink = ThirdPartySink(String::new());
value(&mut sink)?;
Ok(sink.0)
}
let s = third_party_fn("Hello, ".concat_streaming("World").into_write_fn()).unwrap();
assert_eq!(s, "Hello, World");
}
}