pretty_printing/
notation.rs

1use typed_arena::Arena;
2
3pub type NRef<'a> = &'a N<'a>;
4
5// `Notation`, equals the `Doc` in Wadler's Printer
6#[derive(Debug)]
7pub enum N<'a> {
8    Newline,
9    Text(String, u32),
10    Flat(NRef<'a>),
11    Indent(u32, NRef<'a>),
12    Concat(Vec<NRef<'a>>),
13    Choice(NRef<'a>, NRef<'a>),
14}
15
16pub struct NBuilder<'a>(Arena<N<'a>>);
17
18impl<'a> NBuilder<'a> {
19    pub fn new() -> NBuilder<'a> {
20        NBuilder(Arena::new())
21    }
22
23    pub fn nl(&'a self) -> NRef<'a> {
24        self.0.alloc(N::Newline)
25    }
26
27    pub fn txt(&'a self, text: impl ToString) -> NRef<'a> {
28        let string = text.to_string();
29        let width = string.len() as u32;
30        self.0.alloc(N::Text(string, width))
31    }
32
33    pub fn flat(&'a self, n_ref: NRef<'a>) -> NRef<'a> {
34        self.0.alloc(N::Flat(n_ref))
35    }
36
37    pub fn indent(&'a self, indent: u32, n_ref: NRef<'a>) -> NRef<'a> {
38        self.0.alloc(N::Indent(indent, n_ref))
39    }
40
41    pub fn concat(&'a self, n_refs: impl IntoIterator<Item = NRef<'a>>) -> NRef<'a> {
42        let n_vec = n_refs.into_iter().collect::<Vec<_>>();
43        self.0.alloc(N::Concat(n_vec))
44    }
45
46    pub fn choice(&'a self, first: NRef<'a>, second: NRef<'a>) -> NRef<'a> {
47        self.0.alloc(N::Choice(first, second))
48    }
49}