From 4743781cb9af388e407bb9165be417ef7f4bf25a Mon Sep 17 00:00:00 2001 From: kmaasrud Date: Fri, 10 Feb 2023 09:45:43 +0100 Subject: [PATCH] add Render trait --- src/lib.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ce410fe..6e61c98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,9 @@ //! # } //! ``` -use std::fmt::Write; +use std::fmt; +use std::fmt::Write as FmtWrite; +use std::io; #[cfg(feature = "html")] pub mod html; @@ -63,6 +65,55 @@ pub use attr::Attributes; type CowStr<'s> = std::borrow::Cow<'s, str>; +pub trait Render { + /// Push [`Event`]s to a unicode-accepting buffer or stream. + fn push<'s, I: Iterator>, W: fmt::Write>( + &self, + events: I, + out: W, + ) -> fmt::Result; + + /// Write [`Event`]s to a byte sink, encoded as UTF-8. + /// + /// NOTE: This performs many small writes, so IO writes should be buffered with e.g. + /// [`std::io::BufWriter`]. + fn write<'s, I: Iterator>, W: io::Write>( + &self, + events: I, + out: W, + ) -> io::Result<()> { + struct Adapter { + inner: T, + error: io::Result<()>, + } + + impl fmt::Write for Adapter { + fn write_str(&mut self, s: &str) -> fmt::Result { + match self.inner.write_all(s.as_bytes()) { + Ok(()) => Ok(()), + Err(e) => { + self.error = Err(e); + Err(fmt::Error) + } + } + } + } + + let mut out = Adapter { + inner: out, + error: Ok(()), + }; + + match self.push(events, &mut out) { + Ok(()) => Ok(()), + Err(_) => match out.error { + Err(_) => out.error, + _ => Err(io::Error::new(io::ErrorKind::Other, "formatter error")), + }, + } + } +} + /// A Djot event. /// /// A Djot document is represented by a sequence of events. An element may consist of one or