git_branchless_undo/tui/
testing.rs1use std::borrow::Borrow;
4use std::cell::RefCell;
5use std::rc::Rc;
6
7use cursive::backend::Backend;
8use cursive::theme::Color;
9
10pub type Screen = Vec<Vec<char>>;
12
13#[derive(Clone, Debug)]
15pub enum CursiveTestingEvent {
16 Event(cursive::event::Event),
18
19 TakeScreenshot(Rc<RefCell<Screen>>),
22}
23
24#[derive(Debug)]
27pub struct CursiveTestingBackend {
28 events: Vec<CursiveTestingEvent>,
29 event_index: usize,
30 just_emitted_event: bool,
31 screen: RefCell<Screen>,
32 cursor_pos: RefCell<cursive::Vec2>,
33}
34
35impl CursiveTestingBackend {
36 pub fn init(events: Vec<CursiveTestingEvent>) -> Box<dyn Backend> {
38 Box::new(CursiveTestingBackend {
39 events,
40 event_index: 0,
41 just_emitted_event: false,
42 screen: RefCell::new(vec![vec![' '; 120]; 24]),
43 cursor_pos: RefCell::new(cursive::Vec2::zero()),
44 })
45 }
46}
47
48impl Backend for CursiveTestingBackend {
49 fn poll_event(&mut self) -> Option<cursive::event::Event> {
50 if self.just_emitted_event {
53 self.just_emitted_event = false;
54 return None;
55 }
56
57 let event_index = self.event_index;
58 self.event_index += 1;
59 match self.events.get(event_index)?.to_owned() {
60 CursiveTestingEvent::TakeScreenshot(screen_target) => {
61 let mut screen_target = (*screen_target).borrow_mut();
62 screen_target.clone_from(&self.screen.borrow());
63 self.poll_event()
64 }
65 CursiveTestingEvent::Event(event) => {
66 self.just_emitted_event = true;
67 Some(event)
68 }
69 }
70 }
71
72 fn refresh(&mut self) {}
73
74 fn has_colors(&self) -> bool {
75 false
76 }
77
78 fn screen_size(&self) -> cursive::Vec2 {
79 let screen = self.screen.borrow();
80 (screen[0].len(), screen.len()).into()
81 }
82
83 fn move_to(&self, pos: cursive::Vec2) {
84 *self.cursor_pos.borrow_mut() = pos;
85 }
86
87 fn print(&self, text: &str) {
88 let pos = *self.cursor_pos.borrow();
89 let mut col = pos.x;
90 for c in text.chars() {
91 let mut screen = self.screen.borrow_mut();
92 let screen_width = screen[0].len();
93 if col < screen_width {
94 screen[pos.y][col] = c;
95 col += 1;
96 } else {
97 screen[pos.y][screen_width - 1] = '$';
99 break;
100 }
101 }
102 self.cursor_pos.borrow_mut().x = col;
103 }
104
105 fn clear(&self, _color: Color) {
106 let mut screen = self.screen.borrow_mut();
107 for i in 0..screen.len() {
108 for j in 0..screen[i].len() {
109 screen[i][j] = ' ';
110 }
111 }
112 }
113
114 fn set_color(&self, colors: cursive::theme::ColorPair) -> cursive::theme::ColorPair {
115 colors
116 }
117
118 fn set_effect(&self, _effect: cursive::theme::Effect) {}
119
120 fn unset_effect(&self, _effect: cursive::theme::Effect) {}
121
122 fn set_title(&mut self, _title: String) {}
123}
124
125pub fn screen_to_string(screen: &Rc<RefCell<Screen>>) -> String {
128 let screen = Rc::borrow(screen);
129 let screen = RefCell::borrow(screen);
130 screen
131 .iter()
132 .map(|row| {
133 let line: String = row.iter().collect();
134 line.trim_end().to_owned() + "\n"
135 })
136 .collect::<String>()
137 .trim()
138 .to_owned()
139}