1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
pub trait Context {
fn get(&self, s: &str) -> Result<String, String>;
}
#[derive(Debug, Clone, Default)]
pub struct Style {
pub fg: u8,
pub bg: u8,
pub bold: bool,
pub underline: bool,
}
pub trait Print {
fn print(&mut self, s: &str, r: usize, c: usize, style: Option<Style>);
fn size(&self) -> (usize, usize);
}
pub type Line = Vec<Elt>;
pub enum Elt {
Literal(String),
Tag(Tag),
}
pub enum Tag {
Simple(String),
}
pub struct Template {
lines: Vec<Line>,
}
impl Template {
pub fn new(lines: Vec<Line>) -> Self {
Template { lines }
}
pub fn render(&self, context: impl Context, target: impl Print) {
Renderer::new(self)
.render(context, target)
.unwrap_or_else(|err| println!("nope{}", err));
}
}
struct Renderer<'template> {
source: &'template Vec<Line>,
}
impl<'template> Renderer<'template> {
fn new(tpl: &'template Template) -> Self {
Renderer {
source: &tpl.lines,
}
}
fn print_to_target(&self, target: &mut impl Print, s: &str, r: usize, c: usize) -> Result<(), String> {
let (_width, _height) = target.size();
target.print(s, r, c, None);
Ok(())
}
fn render(&mut self, context: impl Context, mut target: impl Print) -> Result<(), String> {
let r: usize = 0;
let c: usize = 0;
for line in self.source {
let mut sb = String::default();
for elt in line {
match elt {
Elt::Literal(s) => sb.push_str(s),
Elt::Tag(t) => match t {
Tag::Simple(s) => {
if let Ok(cs) = context.get(s) {
sb.push_str(&cs);
} else {
}
}
}
}
}
let _ = self.print_to_target(&mut target, &sb, r, c);
}
Ok(())
}
}