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}