1use std::cell::RefCell;
6
7use super::{MarkupFormatter, GenerationError, Formatter};
8use crate::parse::parser::{ParseNode, ParseTree};
9
10#[derive(Debug, Clone)]
11pub struct PlainTextFormatter<'a> {
12 pub tree: ParseTree<'a>,
13 formatters: RefCell<Vec<Box<dyn MarkupFormatter + 'a>>>,
14}
15
16impl<'a> PlainTextFormatter<'a> {
17 pub fn new(tree: ParseTree<'a>) -> Self {
18 Self {
19 tree,
20 formatters: Default::default(),
21 }
22 }
23
24 fn register_formatter<Fmt: MarkupFormatter + 'a>(&self, formatter: Fmt) -> &'a Box<dyn MarkupFormatter + 'a> {
25 let fmts = self.formatters.as_ptr();
26 unsafe {
27 (*fmts).push(Box::new(formatter));
28 (*fmts).last().unwrap()
29 }
30 }
31
32 fn generate_node(&self, f: Formatter, node: &ParseNode<'a>) -> Result<(), GenerationError<'a>> {
33 match node {
34 ParseNode::Symbol(node)
35 | ParseNode::Number(node)
36 | ParseNode::String(node)
37 | ParseNode::Raw(node) => {
38 write!(f, "{}", node.leading_whitespace)?;
39 write!(f, "{}", node.value)?;
40 },
41 ParseNode::List { nodes, leading_whitespace, end_token, .. } => {
42 write!(f, "{}", leading_whitespace)?;
43 write!(f, "(")?;
44 let tree = nodes.to_vec();
45 let text_fmt = PlainTextFormatter::new(tree.into_boxed_slice());
46 let text_fmt = self.register_formatter(text_fmt);
47 text_fmt.generate(f)?;
48 write!(f, "{}", end_token.leading_whitespace)?;
49 write!(f, ")")?;
50
51 },
52 ParseNode::Attribute { keyword, node, leading_whitespace, .. } => {
53 write!(f, "{}", leading_whitespace)?;
54 write!(f, ":{}", keyword)?;
55 self.generate_node(f, node)?;
56 },
57 }
58 Ok(())
59 }
60}
61
62impl<'a> MarkupFormatter for PlainTextFormatter<'a> {
63 fn document(&self) -> Result<String, GenerationError> {
64 self.display()
65 }
66
67 fn generate(&self, f: Formatter) -> Result<(), GenerationError> {
68 let mut tree_iter = self.tree.iter().peekable();
69 while let Some(node) = tree_iter.next() {
70 self.generate_node(f, node)?;
71 }
72 Ok(())
73 }
74}