Skip to main content

utf_railroad/
choice.rs

1use std::fmt;
2use crate::Node;
3
4pub struct Choice {
5    pub(crate) nodes: Vec<Box<dyn Node>>,
6}
7
8impl Choice {
9    pub fn new() -> Self {
10        Self::default()
11    }
12
13    pub fn push(mut self, node: Box<dyn Node>) -> Self {
14        self.nodes.push(node);
15        self
16    }
17}
18
19impl Default for Choice {
20    fn default() -> Self {
21        Self {
22            nodes: Vec::new(),
23        }
24    }
25}
26
27impl Node for Choice {
28    fn get_width(&self) -> usize {
29        let mut width = 0;
30        for n in &self.nodes {
31            width = n.get_width().max(width);
32        }
33        
34        width + 2
35    }
36
37    fn get_height(&self) -> usize {
38        let mut height = 0;
39        for n in &self.nodes {
40            height += n.get_height();
41        }
42        height
43    }
44
45    fn as_str(&self) -> String {
46        let mut max_width = 0;
47        for n in &self.nodes {
48            max_width = n.get_width().max(max_width);
49        }
50
51        let mut ret = String::new();
52
53        for i in 0..self.nodes.len() {
54            let s = self.nodes[i].as_str();
55            let lines = s.lines().collect::<Vec<_>>();
56
57            for y in 0..lines.len() {
58                ret += if i == 0 { 
59                    if y == 1 { "┬" } else if y > 1 { "│" } else { " " }
60                } else if i < self.nodes.len() - 1 { 
61                    if y == 1 { "├" } else { "│" }
62                } else { 
63                    if y == 1 { "╰" } else if y < 1 { "│" } else { " " }
64                };
65
66                let offset = (max_width - lines[y].chars().count()) / 2;
67                let sep2 = if y == 1 { "─" } else { " " };
68                for _ in 0..offset { ret += sep2; }
69                ret += lines[y];
70                for _ in 0..(max_width - offset - lines[y].chars().count()) { ret += sep2; }
71
72                ret += if i == 0 { 
73                    if y == 1 { "┬" } else if y > 1 { "│" } else { " " }
74                } else if i < self.nodes.len() - 1 { 
75                    if y == 1 { "┤" } else { "│" }
76                } else { 
77                    if y == 1 { "╯" } else if y < 1 { "│" } else { " " }
78                };
79                ret += "\n";
80            }
81        }
82
83        ret
84    }
85}
86
87impl fmt::Display for Choice {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        write!(f, "{}", self.as_str())
90    }
91}