Skip to main content

ez_tui/components/mock/
debug.rs

1use crate::{MockComponent, Props, Theme};
2use eztui_derive::MockProps;
3use ratatui::buffer::Buffer;
4use ratatui::layout::{Rect, Size};
5use ratatui::prelude::StatefulWidget;
6use ratatui::widgets::WidgetRef;
7use std::fmt::Debug;
8use tui_widgets::scrollview::{ScrollView, ScrollViewState};
9
10/// A mock component display some value at runtime
11#[derive(Debug, Default, MockProps)]
12pub struct DebugWidgetMock<T>
13where
14    T: Debug,
15{
16    props: Props,
17    value: Option<T>,
18    scroll_view_state: ScrollViewState,
19}
20
21impl<T> DebugWidgetMock<T>
22where
23    T: Debug,
24{
25    /// Create a new [`DebugWidgetMock`] component with the given value to debug
26    #[must_use]
27    pub fn with_value(value: T) -> Self {
28        Self {
29            props: Props::default(),
30            value: Some(value),
31            scroll_view_state: ScrollViewState::default(),
32        }
33    }
34
35    /// Create a new [`DebugWidgetMock`] component with no value yet.
36    /// Call [`set`] to set the value later.
37    #[must_use]
38    pub fn empty() -> Self {
39        Self {
40            props: Props::default(),
41            value: None,
42            scroll_view_state: ScrollViewState::default(),
43        }
44    }
45
46    /// Set the value to be debugged
47    pub fn set(&mut self, value: T) {
48        self.value = Some(value);
49    }
50
51    /// Unset the value to be debugged
52    pub fn unset(&mut self) {
53        self.value = None;
54    }
55}
56
57impl<T> MockComponent for DebugWidgetMock<T>
58where
59    T: Debug,
60{
61    fn draw(&mut self, area: Rect, buf: &mut Buffer, theme: &Theme) {
62        let text = if let Some(val) = &self.value {
63            format!("{val:#?}")
64        } else {
65            "Value not set".to_string()
66        };
67
68        let paragraph = theme.paragraph(text, Some(&self.props));
69        let height: u16 = paragraph
70            .line_count(area.width)
71            .try_into()
72            .unwrap_or(u16::MAX);
73        let width = if buf.area.height < height {
74            buf.area.width - 1
75        } else {
76            buf.area.width
77        };
78
79        let mut scroll_view = ScrollView::new(Size::new(width, height));
80        paragraph.render_ref(scroll_view.buf_mut().area, scroll_view.buf_mut());
81        scroll_view.render(area, buf, &mut self.scroll_view_state);
82    }
83}