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
use std::io;
use crate::cursor::CursorPosition;
use crate::line::Line;
use crate::update::UpdateBatch;
use crate::utility::move_cursor_to;
use crate::result::Result;
pub(crate) struct InterfaceState {
pub(crate) cursor: CursorPosition,
pub(crate) lines: Vec<Line>,
}
pub struct TTYInterface<'a> {
pub(crate) writer: &'a mut dyn io::Write,
pub(crate) state: InterfaceState,
}
impl TTYInterface<'_> {
pub fn new(writer: &mut dyn io::Write) -> TTYInterface {
TTYInterface {
writer,
state: InterfaceState {
lines: Vec::new(),
cursor: CursorPosition::init(0, 0)
}
}
}
pub fn start_update(&self) -> UpdateBatch {
UpdateBatch { steps: Vec::new() }
}
pub fn perform_update(&mut self, batch: UpdateBatch) -> Result<()> {
let mut update_cursor = self.state.cursor;
for mut step in batch.steps {
step.do_update(self, &mut update_cursor)?;
}
move_cursor_to(self.writer, &mut update_cursor, &self.state.cursor)?;
self.writer.flush()?;
Ok(())
}
pub fn end(&mut self) -> Result<()> {
write!(self.writer, "{}", "\n".repeat(self.state.lines.len()))?;
self.writer.flush()?;
Ok(())
}
}