rustdoc/display.rs
1//! Various utilities for working with [`fmt::Display`] implementations.
2
3use std::fmt::{self, Display, Formatter};
4
5pub(crate) trait Joined: IntoIterator {
6 /// Takes an iterator over elements that implement [`Display`], and format them into `f`, separated by `sep`.
7 ///
8 /// This is similar to [`Itertools::format`](itertools::Itertools::format), but instead of returning an implementation of `Display`,
9 /// it formats directly into a [`Formatter`].
10 ///
11 /// 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)
12 /// was already called (`joined`'s API doesn't allow it be called more than once).
13 fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result;
14}
15
16impl<I, T> Joined for I
17where
18 I: IntoIterator<Item = T>,
19 T: Display,
20{
21 fn joined(self, sep: &str, f: &mut Formatter<'_>) -> fmt::Result {
22 let mut iter = self.into_iter();
23 let Some(first) = iter.next() else { return Ok(()) };
24 first.fmt(f)?;
25 for item in iter {
26 f.write_str(sep)?;
27 item.fmt(f)?;
28 }
29 Ok(())
30 }
31}
32
33pub(crate) trait MaybeDisplay {
34 /// For a given `Option<T: Display>`, returns a `Display` implementation that will display `t` if `Some(t)`, or nothing if `None`.
35 fn maybe_display(self) -> impl Display;
36}
37
38impl<T: Display> MaybeDisplay for Option<T> {
39 fn maybe_display(self) -> impl Display {
40 fmt::from_fn(move |f| {
41 if let Some(t) = self.as_ref() {
42 t.fmt(f)?;
43 }
44 Ok(())
45 })
46 }
47}