blob: ba09863dcaa9071554e66e2179ccc6d28243a437 [file] [log] [blame]
extern crate pretty;
use pretty::{BoxAllocator, DocAllocator, DocBuilder};
use std::io;
use std::str;
#[derive(Clone, Debug)]
pub struct Forest<'a>(&'a [Tree<'a>]);
impl<'a> Forest<'a> {
fn forest(forest: &'a [Tree<'a>]) -> Forest<'a> {
Forest(forest)
}
fn nil() -> Forest<'a> {
Forest(&[])
}
fn bracket<'b, D, A>(&'b self, allocator: &'b D) -> DocBuilder<'b, D, A>
where
D: DocAllocator<'b, A>,
D::Doc: Clone,
A: Clone,
{
if (self.0).len() == 0 {
allocator.nil()
} else {
allocator
.text("[")
.append(allocator.newline().append(self.pretty(allocator)).nest(2))
.append(allocator.newline())
.append(allocator.text("]"))
}
}
fn pretty<'b, D, A>(&'b self, allocator: &'b D) -> DocBuilder<'b, D, A>
where
D: DocAllocator<'b, A>,
D::Doc: Clone,
A: Clone,
{
let forest = self.0;
let separator = allocator.text(",").append(allocator.newline());
allocator.intersperse(
forest.into_iter().map(|tree| tree.pretty(allocator)),
separator,
)
}
}
#[derive(Clone, Debug)]
pub struct Tree<'a> {
node: String,
forest: Forest<'a>,
}
impl<'a> Tree<'a> {
pub fn node(node: &str) -> Tree<'a> {
Tree {
node: node.to_string(),
forest: Forest::nil(),
}
}
pub fn node_with_forest(node: &str, forest: &'a [Tree<'a>]) -> Tree<'a> {
Tree {
node: node.to_string(),
forest: Forest::forest(forest),
}
}
pub fn pretty<'b, D, A>(&'b self, allocator: &'b D) -> DocBuilder<'b, D, A>
where
D: DocAllocator<'b, A>,
D::Doc: Clone,
A: Clone,
{
allocator
.text(&self.node[..])
.append((self.forest).bracket(allocator))
.group()
}
}
#[allow(dead_code)]
pub fn main() {
let allocator = BoxAllocator;
let bbbbbbs = [Tree::node("ccc"), Tree::node("dd")];
let ffffs = [Tree::node("gg"), Tree::node("hhh"), Tree::node("ii")];
let aaas = [
Tree::node_with_forest("bbbbbb", &bbbbbbs),
Tree::node("eee"),
Tree::node_with_forest("ffff", &ffffs),
];
let example = Tree::node_with_forest("aaaa", &aaas);
let err_msg = "<buffer is not a utf-8 encoded string>";
// try writing to stdout
{
print!("\nwriting to stdout directly:\n");
let mut out = io::stdout();
example.pretty::<_, ()>(&allocator).1.render(70, &mut out)
// try writing to memory
}.and_then(|()| {
print!("\nwriting to string then printing:\n");
let mut mem = Vec::new();
example
.pretty::<_, ()>(&allocator)
.1
.render(70, &mut mem)
// print to console from memory
.map(|()| {
let res = str::from_utf8(&mem).unwrap_or(err_msg);
println!("{}", res)
})
// print an error if anything failed
})
.unwrap_or_else(|err| println!("error: {}", err));
}