Skip to main content

ez_tui/utils/
props.rs

1#![allow(missing_docs)]
2//FEAT: the whole Attribute and AttrValue concept is copied from tui-realm. I kee it as it is for now but we probably work on it later. I'll then document it
3
4use crate::BorderTheme;
5use hashlink::LinkedHashMap;
6use ratatui::layout::{Alignment, Direction, Layout};
7use ratatui::style::{Color, Style};
8
9#[derive(Debug, Default, PartialEq, Clone)]
10pub struct Props {
11    attrs: LinkedHashMap<Attribute, AttrValue>,
12}
13
14impl Props {
15    #[must_use]
16    pub fn get(&self, query: Attribute) -> Option<AttrValue> {
17        self.attrs.get(&query).cloned()
18    }
19
20    #[must_use]
21    pub fn get_or(&self, query: Attribute, default: AttrValue) -> AttrValue {
22        self.get(query).unwrap_or(default)
23    }
24
25    #[must_use]
26    pub fn get_ref(&self, query: Attribute) -> Option<&AttrValue> {
27        self.attrs.get(&query)
28    }
29
30    pub fn set(&mut self, query: Attribute, value: AttrValue) {
31        self.attrs.insert(query, value);
32    }
33
34    /// Shorthand to get the focus
35    #[must_use]
36    pub fn has_focus(&self) -> bool {
37        self.attrs
38            .get(&Attribute::Focus)
39            .and_then(AttrValue::as_flag)
40            .unwrap_or(false)
41    }
42}
43
44#[derive(Debug, Eq, PartialEq, Copy, Clone, PartialOrd, Hash)]
45pub enum Attribute {
46    Alignment,
47
48    Background,
49
50    Borders,
51
52    Color,
53
54    Content,
55
56    Dataset,
57
58    Direction,
59
60    Disabled,
61
62    Display,
63
64    Focus,
65
66    FocusStyle,
67
68    Foreground,
69
70    Height,
71
72    HighlightedStr,
73
74    HighlightedColor,
75
76    InputLength,
77
78    InputType,
79
80    Layout,
81
82    Palette,
83
84    Rewind,
85
86    Shape,
87
88    Scroll,
89
90    ScrollStep,
91
92    Style,
93
94    Text,
95
96    TextAlign,
97
98    TextProps,
99
100    TextWrap,
101
102    Title,
103
104    Value,
105
106    Width,
107
108    Custom(&'static str),
109}
110
111#[derive(Debug, PartialEq, Clone)]
112pub enum AttrValue {
113    Alignment(Alignment),
114    Borders(BorderTheme),
115    Color(Color),
116    Direction(Direction),
117    Flag(bool),
118    Layout(Layout),
119    Length(usize),
120    Number(isize),
121    Size(u16),
122    String(String),
123    Style(Style),
124    Title((String, Alignment)),
125}
126
127impl AttrValue {
128    #[must_use]
129    pub fn as_alignment(&self) -> Option<Alignment> {
130        match self {
131            // cheap copy, so no reference
132            AttrValue::Alignment(v) => Some(*v),
133            _ => None,
134        }
135    }
136
137    #[must_use]
138    pub fn as_borders(&self) -> Option<&BorderTheme> {
139        match self {
140            AttrValue::Borders(v) => Some(v),
141            _ => None,
142        }
143    }
144
145    #[must_use]
146    pub fn as_color(&self) -> Option<Color> {
147        match self {
148            // cheap copy, so no reference
149            AttrValue::Color(v) => Some(*v),
150            _ => None,
151        }
152    }
153
154    #[must_use]
155    pub fn as_direction(&self) -> Option<Direction> {
156        match self {
157            // cheap copy, so no reference
158            AttrValue::Direction(v) => Some(*v),
159            _ => None,
160        }
161    }
162
163    #[must_use]
164    pub fn as_flag(&self) -> Option<bool> {
165        match self {
166            // cheap copy, so no reference
167            AttrValue::Flag(v) => Some(*v),
168            _ => None,
169        }
170    }
171
172    #[must_use]
173    pub fn as_layout(&self) -> Option<&Layout> {
174        match self {
175            AttrValue::Layout(v) => Some(v),
176            _ => None,
177        }
178    }
179
180    #[must_use]
181    pub fn as_length(&self) -> Option<usize> {
182        match self {
183            // cheap copy, so no reference
184            AttrValue::Length(v) => Some(*v),
185            _ => None,
186        }
187    }
188
189    #[must_use]
190    pub fn as_number(&self) -> Option<isize> {
191        match self {
192            // cheap copy, so no reference
193            AttrValue::Number(v) => Some(*v),
194            _ => None,
195        }
196    }
197
198    #[must_use]
199    pub fn as_size(&self) -> Option<u16> {
200        match self {
201            // cheap copy, so no reference
202            AttrValue::Size(v) => Some(*v),
203            _ => None,
204        }
205    }
206
207    #[must_use]
208    pub fn as_string(&self) -> Option<String> {
209        match self {
210            AttrValue::String(v) => Some(v).cloned(),
211            _ => None,
212        }
213    }
214
215    #[must_use]
216    pub fn as_style(&self) -> Option<Style> {
217        match self {
218            // cheap copy, so no reference
219            AttrValue::Style(v) => Some(*v),
220            _ => None,
221        }
222    }
223    #[must_use]
224    pub fn as_title(&self) -> Option<&(String, Alignment)> {
225        match self {
226            AttrValue::Title(v) => Some(v),
227            _ => None,
228        }
229    }
230}