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}
33
34impl CursiveTestingBackend {
35 pub fn init(events: Vec<CursiveTestingEvent>) -> Box<dyn Backend> {
37 Box::new(CursiveTestingBackend {
38 events,
39 event_index: 0,
40 just_emitted_event: false,
41 screen: RefCell::new(vec![vec![' '; 120]; 24]),
42 })
43 }
44}
45
46impl Backend for CursiveTestingBackend {
47 fn poll_event(&mut self) -> Option<cursive::event::Event> {
48 if self.just_emitted_event {
51 self.just_emitted_event = false;
52 return None;
53 }
54
55 let event_index = self.event_index;
56 self.event_index += 1;
57 match self.events.get(event_index)?.to_owned() {
58 CursiveTestingEvent::TakeScreenshot(screen_target) => {
59 let mut screen_target = (*screen_target).borrow_mut();
60 screen_target.clone_from(&self.screen.borrow());
61 self.poll_event()
62 }
63 CursiveTestingEvent::Event(event) => {
64 self.just_emitted_event = true;
65 Some(event)
66 }
67 }
68 }
69
70 fn refresh(&mut self) {}
71
72 fn has_colors(&self) -> bool {
73 false
74 }
75
76 fn screen_size(&self) -> cursive::Vec2 {
77 let screen = self.screen.borrow();
78 (screen[0].len(), screen.len()).into()
79 }
80
81 fn print_at(&self, pos: cursive::Vec2, text: &str) {
82 for (i, c) in text.chars().enumerate() {
83 let mut screen = self.screen.borrow_mut();
84 let screen_width = screen[0].len();
85 if pos.x + i < screen_width {
86 screen[pos.y][pos.x + i] = c;
87 } else {
88 screen[pos.y][screen_width - 1] = '$';
90 }
91 }
92 }
93
94 fn clear(&self, _color: Color) {
95 let mut screen = self.screen.borrow_mut();
96 for i in 0..screen.len() {
97 for j in 0..screen[i].len() {
98 screen[i][j] = ' ';
99 }
100 }
101 }
102
103 fn set_color(&self, colors: cursive::theme::ColorPair) -> cursive::theme::ColorPair {
104 colors
105 }
106
107 fn set_effect(&self, _effect: cursive::theme::Effect) {}
108
109 fn unset_effect(&self, _effect: cursive::theme::Effect) {}
110
111 fn set_title(&mut self, _title: String) {}
112}
113
114pub fn screen_to_string(screen: &Rc<RefCell<Screen>>) -> String {
117 let screen = Rc::borrow(screen);
118 let screen = RefCell::borrow(screen);
119 screen
120 .iter()
121 .map(|row| {
122 let line: String = row.iter().collect();
123 line.trim_end().to_owned() + "\n"
124 })
125 .collect::<String>()
126 .trim()
127 .to_owned()
128}