about summary refs log tree commit diff
path: root/src/librustdoc/display.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/display.rs')
-rw-r--r--src/librustdoc/display.rs47
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(())
+        })
+    }
+}