pretty_util/
lib.rs

1pub use pretty;
2use pretty::RcDoc;
3
4pub trait PrettySimple<'a>: Sized {
5    fn pprint(self) -> RcDoc<'a>;
6
7    fn append<P: PrettySimple<'a>>(self, other: P) -> RcDoc<'a> {
8        self.pprint().append(other.pprint())
9    }
10}
11
12impl<'a> PrettySimple<'a> for &'a str {
13    fn pprint(self) -> RcDoc<'a> {
14        RcDoc::text(self)
15    }
16}
17
18impl<'a> PrettySimple<'a> for RcDoc<'a> {
19    fn pprint(self) -> RcDoc<'a> {
20        self
21    }
22}
23
24pub fn surrounded_by<'a, P: PrettySimple<'a>>(l: &'a str, x: P, r: &'a str) -> RcDoc<'a> {
25    RcDoc::text(l)
26        .append(RcDoc::softline())
27        .append(x.pprint().group())
28        .append(RcDoc::softline())
29        .append(r)
30}
31
32pub fn brackets<'a, P: PrettySimple<'a>>(x: P) -> RcDoc<'a> {
33    surrounded_by("[", x, "]")
34}
35
36pub fn parens<'a, P: PrettySimple<'a>>(x: P) -> RcDoc<'a> {
37    surrounded_by("(", x, ")")
38}
39
40pub fn braces<'a, P: PrettySimple<'a>>(x: P) -> RcDoc<'a> {
41    surrounded_by("{", x, "}")
42}
43
44pub fn binop<'a, P: PrettySimple<'a>, Q: PrettySimple<'a>>(l: P, op: &'a str, r: Q) -> RcDoc<'a> {
45    l.pprint()
46        .append(RcDoc::line())
47        .append(op)
48        .append(RcDoc::line())
49        .append(r.pprint())
50        .group()
51}
52
53pub fn intersperse<'a, P: PrettySimple<'a> + 'a, I: Iterator<Item = P>, Q: PrettySimple<'a>>(
54    items: I,
55    separator: Q,
56) -> RcDoc<'a> {
57    RcDoc::intersperse(items.map(|i| i.pprint()), separator.pprint())
58}
59
60pub fn concat<'a, P: PrettySimple<'a> + 'a, I: Iterator<Item = P>>(items: I) -> RcDoc<'a> {
61    RcDoc::concat(items.map(|i| i.pprint()))
62}
63
64pub fn tuple<'a, P: PrettySimple<'a> + 'a, I: Iterator<Item = P>>(items: I) -> RcDoc<'a> {
65    braces(intersperse(items, ",".append(RcDoc::line())).group())
66}
67
68pub fn t<'a, S: Into<String>>(s: S) -> RcDoc<'a> {
69    RcDoc::text(s.into())
70}
71
72#[macro_export]
73macro_rules! doc {
74    (@fold $acc:tt) => {
75        $acc
76    };
77    (@fold $acc:tt $head:tt $($tail:tt)*) => {
78        doc!(@fold {$acc.append($head)} $($tail)*)
79    };
80    ($($arg:expr),+) => {{
81        doc!(@fold $({$arg.pprint()})*)
82    }}
83}
84
85#[macro_export]
86macro_rules! docf {
87    ($s:literal) => {
88        $crate::pretty::RcDoc::text(format!($s))
89    };
90    ($s:literal, $($arg:expr),+) => {
91        $crate::pretty::RcDoc::text(format!($s, $($arg),+))
92    };
93}
94
95pub struct Ln;
96
97impl<'a> PrettySimple<'a> for Ln {
98    fn pprint(self) -> RcDoc<'a> {
99        RcDoc::line()
100    }
101}