1use delimiters::Delimiters;
2use std::fmt::Write;
3
4impl<W: Write + ?Sized> FmtAdapter for W {}
5pub trait FmtAdapter: Write {
6 fn indent(&mut self) -> Indent<Self> {
7 Indent { f: self }
8 }
9
10 fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> {
11 Delimit::new(self, delim)
12 }
13
14 fn delimit_with(&mut self, open: &'static str, close: &'static str) -> Delimit<Self> {
15 Delimit::new(self, Delimiters { open, close })
16 }
17}
18
19pub struct Indent<'f, F: Write + ?Sized> {
21 f: &'f mut F,
22}
23
24impl<F: Write + ?Sized> Write for Indent<'_, F> {
25 fn write_str(&mut self, s: &str) -> std::fmt::Result {
26 for s in s.split_inclusive('\n') {
27 self.f.write_str(s)?;
28 if s.ends_with('\n') {
29 self.f.write_str(" ")?;
30 }
31 }
32 Ok(())
33 }
34}
35
36pub struct Delimit<'f, F: Write + ?Sized> {
38 f: Indent<'f, F>,
39 delim: Delimiters,
40}
41impl<'f, F: Write + ?Sized> Delimit<'f, F> {
42 pub fn new(f: &'f mut F, delim: Delimiters) -> Self {
43 let mut f = f.indent();
44 let _ = f.write_str(delim.open);
45 Self { f, delim }
46 }
47}
48impl<F: Write + ?Sized> Drop for Delimit<'_, F> {
49 fn drop(&mut self) {
50 let Self { f: Indent { f, .. }, delim } = self;
51 let _ = f.write_str(delim.close);
52 }
53}
54
55impl<F: Write + ?Sized> Write for Delimit<'_, F> {
56 fn write_str(&mut self, s: &str) -> std::fmt::Result {
57 self.f.write_str(s)
58 }
59}
60
61pub mod delimiters {
62 #![allow(dead_code)]
63 #[derive(Clone, Copy, Debug)]
64 pub struct Delimiters {
65 pub open: &'static str,
66 pub close: &'static str,
67 }
68 pub const SPACED_BRACES: Delimiters = Delimiters { open: " {\n", close: "\n}" };
70 pub const BRACES: Delimiters = Delimiters { open: "{\n", close: "\n}" };
72 pub const PARENS: Delimiters = Delimiters { open: "(\n", close: "\n)" };
74 pub const SQUARE: Delimiters = Delimiters { open: "[\n", close: "\n]" };
76 pub const INLINE_BRACES: Delimiters = Delimiters { open: "{ ", close: " }" };
78 pub const INLINE_PARENS: Delimiters = Delimiters { open: "(", close: ")" };
80 pub const INLINE_SQUARE: Delimiters = Delimiters { open: "[", close: "]" };
82}