diff options
Diffstat (limited to 'src/librustdoc/display.rs')
| -rw-r--r-- | src/librustdoc/display.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs new file mode 100644 index 00000000000..ee8dde013ee --- /dev/null +++ b/src/librustdoc/display.rs @@ -0,0 +1,47 @@ +//! Various utilities for working with [`fmt::Display`] implementations. + +use std::fmt::{self, Display, Formatter}; + +pub(crate) trait Joined: IntoIterator { + /// Takes an iterator over elements that implement [`Display`], and format them into `f`, separated by `sep`. + /// + /// This is similar to [`Itertools::format`](itertools::Itertools::format), but instead of returning an implementation of `Display`, + /// it formats directly into a [`Formatter`]. + /// + /// The performance of `joined` is slightly better than `format`, since it doesn't need to use a `Cell` to keep track of whether [`fmt`](Display::fmt) + /// was already called (`joined`'s API doesn't allow it be called more than once). + fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result; +} + +impl<I, T> Joined for I +where + I: IntoIterator<Item = T>, + T: Display, +{ + fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result { + let mut iter = self.into_iter(); + let Some(first) = iter.next() else { return Ok(()) }; + first.fmt(f)?; + while let Some(item) = iter.next() { + f.write_str(sep)?; + item.fmt(f)?; + } + Ok(()) + } +} + +pub(crate) trait MaybeDisplay { + /// For a given `Option<T: Display>`, returns a `Display` implementation that will display `t` if `Some(t)`, or nothing if `None`. + fn maybe_display(self) -> impl Display; +} + +impl<T: Display> MaybeDisplay for Option<T> { + fn maybe_display(self) -> impl Display { + fmt::from_fn(move |f| { + if let Some(t) = self.as_ref() { + t.fmt(f)?; + } + Ok(()) + }) + } +} |
