Skip to main content

utf_railroad/
nonterminal.rs

1use std::fmt;
2use crate::Node;
3
4pub struct NonTerminal {
5    pub(crate) contents: String,
6}
7
8impl NonTerminal {
9    pub fn new(contents: &str) -> Self {
10        Self { 
11            contents: String::from(contents),
12        }
13    }
14}
15
16impl Node for NonTerminal {
17    fn get_width(&self) -> usize {
18        let mut width = 0;
19        for line in self.contents.lines() {
20            width = line.len().max(width);
21        }
22        width + 4
23    }
24
25    fn get_height(&self) -> usize {
26        self.contents.lines().collect::<Vec<_>>().len() + 2
27    }
28
29    fn as_str(&self) -> String {
30        let width = self.get_width() - 4;
31        let mut ret = String::new();
32
33        // top
34        ret += "┏";
35        for _ in 0..width+2 { ret += "━"; }
36        ret += "┓\n";
37
38        // contents
39        for line in self.contents.lines() {
40            let offset = (width - line.len())/2;
41            ret += "┃ ";
42            for _ in 0..offset { ret += " "; };
43            ret += line;
44            for _ in 0..(width - offset - line.len()) {ret += " ";}
45            ret += " ┃\n";
46        }
47
48        // bottom
49        ret += "┗";
50        for _ in 0..width+2 { ret += "━"; }
51        ret += "┛";
52
53        ret
54    }
55}
56
57impl fmt::Display for NonTerminal {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        write!(f, "{}", self.as_str())
60    }
61}