vast 0.3.3

Verilog AST library
Documentation
use pretty::RcDoc;

pub const PRETTY_WIDTH: usize = 100;
pub const PRETTY_INDENT: isize = 4;

pub trait PrettyPrint {
    fn to_doc(&self) -> RcDoc<()>;

    fn to_pretty_with_width(&self, width: usize) -> String {
        let mut w = Vec::new();
        self.to_doc().render(width, &mut w).unwrap();
        String::from_utf8(w).unwrap()
    }

    fn to_pretty(&self) -> String {
        self.to_pretty_with_width(PRETTY_WIDTH)
    }

    fn render_fmt(&self, f: &mut impl std::fmt::Write) -> std::fmt::Result {
        let doc = self.to_doc();
        doc.render_fmt(PRETTY_WIDTH, f)
    }
}

pub trait PrettyHelper<'a>: Sized {
    fn surround(self, pre: &'a str, post: &'a str) -> Self;

    fn parens(self) -> Self {
        self.surround("(", ")")
    }

    fn brackets(self) -> Self {
        self.surround("[", "]")
    }

    fn braces(self) -> Self {
        self.surround("{", "}")
    }

    fn quotes(self) -> Self {
        self.surround("\"", "\"")
    }

    fn stars(self) -> Self {
        self.surround("*", "*")
    }

    fn begin_end(self) -> Self {
        self.surround("begin", "end")
    }

    fn case_endcase(self) -> Self {
        self.surround("case", "endcase")
    }

    fn func_endfunc(self) -> Self {
        self.surround("function", "endfunction")
    }

    fn module_endmodule(self) -> Self {
        self.surround("module", "endmodule")
    }
}

impl<'a, A> PrettyHelper<'a> for RcDoc<'a, A> {
    fn surround(self, l: &'a str, r: &'a str) -> Self {
        RcDoc::text(l).append(self).append(RcDoc::text(r))
    }
}

pub fn intersperse<'a>(iter: impl Iterator<Item = RcDoc<'a>>, separator: RcDoc<'a>) -> RcDoc<'a> {
    RcDoc::intersperse(iter, separator)
}

pub fn block(body: RcDoc<()>) -> RcDoc<()> {
    RcDoc::nil()
        .append(RcDoc::hardline())
        .append(body)
        .nest(PRETTY_INDENT)
        .append(RcDoc::hardline())
}

pub fn block_with_braces<'a>(name: RcDoc<'a>, body: RcDoc<'a>) -> RcDoc<'a> {
    name.append(RcDoc::space()).append(block(body).braces())
}

pub fn block_with_parens<'a>(name: RcDoc<'a>, body: RcDoc<'a>) -> RcDoc<'a> {
    name.append(RcDoc::space()).append(block(body).parens())
}