use crate::spec_ai_tui::buffer::Buffer;
use crate::spec_ai_tui::geometry::Rect;
pub trait Widget {
fn render(&self, area: Rect, buf: &mut Buffer);
}
pub trait StatefulWidget {
type State;
fn render(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State);
}
impl<W: Widget> StatefulWidget for W {
type State = ();
fn render(&self, area: Rect, buf: &mut Buffer, _state: &mut Self::State) {
Widget::render(self, area, buf);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::spec_ai_tui::style::Style;
struct TestWidget {
text: String,
}
impl Widget for TestWidget {
fn render(&self, area: Rect, buf: &mut Buffer) {
buf.set_string(area.x, area.y, &self.text, Style::default());
}
}
#[test]
fn test_widget_render() {
let widget = TestWidget {
text: "Hello".to_string(),
};
let area = Rect::new(0, 0, 20, 5);
let mut buf = Buffer::new(area);
Widget::render(&widget, area, &mut buf);
assert_eq!(buf.get(0, 0).unwrap().symbol, "H");
assert_eq!(buf.get(4, 0).unwrap().symbol, "o");
}
struct CounterWidget;
impl StatefulWidget for CounterWidget {
type State = u32;
fn render(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
let text = format!("Count: {}", state);
buf.set_string(area.x, area.y, &text, Style::default());
*state += 1;
}
}
#[test]
fn test_stateful_widget_render() {
let widget = CounterWidget;
let area = Rect::new(0, 0, 20, 5);
let mut buf = Buffer::new(area);
let mut state = 0u32;
widget.render(area, &mut buf, &mut state);
assert_eq!(state, 1);
widget.render(area, &mut buf, &mut state);
assert_eq!(state, 2);
}
}