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