1use std::fmt::{self, Display, Formatter, FormattingOptions};
4
5pub(crate) trait Joined: IntoIterator {
6 fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result;
14}
15
16impl<I, T> Joined for I
17where
18 I: Iterator<Item = T>,
19 T: Display,
20{
21 fn joined(&mut self, sep: impl Display, f: &mut Formatter<'_>) -> fmt::Result {
22 let Some(first) = self.next() else { return Ok(()) };
23 first.fmt(f)?;
24 for item in self {
25 sep.fmt(f)?;
26 item.fmt(f)?;
27 }
28 Ok(())
29 }
30}
31
32pub(crate) trait MaybeDisplay {
33 fn maybe_display(self) -> impl Display;
35}
36
37impl<T: Display> MaybeDisplay for Option<T> {
38 fn maybe_display(self) -> impl Display {
39 fmt::from_fn(move |f| {
40 if let Some(t) = self.as_ref() {
41 t.fmt(f)?;
42 }
43 Ok(())
44 })
45 }
46}
47
48#[derive(Clone, Copy)]
49pub(crate) struct Wrapped<T> {
50 prefix: T,
51 suffix: T,
52}
53
54pub(crate) enum AngleBracket {
55 Open,
56 Close,
57}
58
59impl Display for AngleBracket {
60 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61 f.write_str(match (self, f.alternate()) {
62 (Self::Open, true) => "<",
63 (Self::Open, false) => "<",
64 (Self::Close, true) => ">",
65 (Self::Close, false) => ">",
66 })
67 }
68}
69
70impl Wrapped<AngleBracket> {
71 pub(crate) fn with_angle_brackets() -> Self {
72 Self { prefix: AngleBracket::Open, suffix: AngleBracket::Close }
73 }
74}
75
76impl Wrapped<char> {
77 pub(crate) fn with_parens() -> Self {
78 Self { prefix: '(', suffix: ')' }
79 }
80
81 pub(crate) fn with_square_brackets() -> Self {
82 Self { prefix: '[', suffix: ']' }
83 }
84}
85
86impl<T: Display> Wrapped<T> {
87 pub(crate) fn with(prefix: T, suffix: T) -> Self {
88 Self { prefix, suffix }
89 }
90
91 pub(crate) fn when(self, if_: bool) -> Wrapped<impl Display> {
92 Wrapped {
93 prefix: if_.then_some(self.prefix).maybe_display(),
94 suffix: if_.then_some(self.suffix).maybe_display(),
95 }
96 }
97
98 pub(crate) fn wrap_fn(
99 self,
100 content: impl Fn(&mut Formatter<'_>) -> fmt::Result,
101 ) -> impl Display {
102 fmt::from_fn(move |f| {
103 self.prefix.fmt(f)?;
104 content(f)?;
105 self.suffix.fmt(f)
106 })
107 }
108
109 pub(crate) fn wrap<C: Display>(self, content: C) -> impl Display {
110 self.wrap_fn(move |f| content.fmt(f))
111 }
112}
113
114#[derive(Clone, Copy)]
115pub(crate) struct WithOpts {
116 opts: FormattingOptions,
117}
118
119impl WithOpts {
120 pub(crate) fn from(f: &Formatter<'_>) -> Self {
121 Self { opts: f.options() }
122 }
123
124 pub(crate) fn display(self, t: impl Display) -> impl Display {
125 fmt::from_fn(move |f| {
126 let mut f = f.with_options(self.opts);
127 t.fmt(&mut f)
128 })
129 }
130}