dampen_core/codegen/
status_mapping.rs1use proc_macro2::TokenStream;
36use quote::quote;
37
38use crate::WidgetKind;
39
40pub fn generate_status_mapping(
67 widget_kind: &WidgetKind,
68 status_ident: &syn::Ident,
69) -> Option<TokenStream> {
70 match widget_kind {
71 WidgetKind::Button => Some(generate_button_status_mapping(status_ident)),
72 WidgetKind::TextInput => Some(generate_text_input_status_mapping(status_ident)),
73 WidgetKind::Checkbox => Some(generate_checkbox_status_mapping(status_ident)),
74 WidgetKind::Radio => Some(generate_radio_status_mapping(status_ident)),
75 WidgetKind::Toggler => Some(generate_toggler_status_mapping(status_ident)),
76 WidgetKind::Slider => Some(generate_slider_status_mapping(status_ident)),
77 WidgetKind::PickList => Some(generate_picklist_status_mapping(status_ident)),
78 WidgetKind::ComboBox => Some(generate_combo_box_status_mapping(status_ident)),
79 _ => None, }
81}
82
83fn generate_button_status_mapping(status_ident: &syn::Ident) -> TokenStream {
91 quote! {
92 {
93 use iced::widget::button::Status;
94 match #status_ident {
95 Status::Active => None,
96 Status::Hovered => Some(dampen_core::ir::WidgetState::Hover),
97 Status::Pressed => Some(dampen_core::ir::WidgetState::Active),
98 Status::Disabled => Some(dampen_core::ir::WidgetState::Disabled),
99 }
100 }
101 }
102}
103
104fn generate_text_input_status_mapping(status_ident: &syn::Ident) -> TokenStream {
112 quote! {
113 {
114 use iced::widget::text_input::Status;
115 match #status_ident {
116 Status::Active => None,
117 Status::Hovered => Some(dampen_core::ir::WidgetState::Hover),
118 Status::Focused { .. } => Some(dampen_core::ir::WidgetState::Focus),
119 Status::Disabled => Some(dampen_core::ir::WidgetState::Disabled),
120 }
121 }
122 }
123}
124
125fn generate_checkbox_status_mapping(status_ident: &syn::Ident) -> TokenStream {
134 quote! {
135 {
136 use iced::widget::checkbox::Status;
137 match #status_ident {
138 Status::Active { .. } => None,
139 Status::Hovered { .. } => Some(dampen_core::ir::WidgetState::Hover),
140 Status::Disabled { .. } => Some(dampen_core::ir::WidgetState::Disabled),
141 }
142 }
143 }
144}
145
146fn generate_radio_status_mapping(status_ident: &syn::Ident) -> TokenStream {
155 quote! {
156 {
157 use iced::widget::radio::Status;
158 match #status_ident {
159 Status::Active { .. } => None,
160 Status::Hovered { .. } => Some(dampen_core::ir::WidgetState::Hover),
161 }
162 }
163 }
164}
165
166fn generate_toggler_status_mapping(status_ident: &syn::Ident) -> TokenStream {
175 quote! {
176 {
177 use iced::widget::toggler::Status;
178 match #status_ident {
179 Status::Active { .. } => None,
180 Status::Hovered { .. } => Some(dampen_core::ir::WidgetState::Hover),
181 Status::Disabled { .. } => Some(dampen_core::ir::WidgetState::Disabled),
182 }
183 }
184 }
185}
186
187fn generate_slider_status_mapping(status_ident: &syn::Ident) -> TokenStream {
197 quote! {
198 {
199 use iced::widget::slider::Status;
200 match #status_ident {
201 Status::Active => None,
202 Status::Hovered => Some(dampen_core::ir::WidgetState::Hover),
203 Status::Dragged => Some(dampen_core::ir::WidgetState::Active),
204 }
205 }
206 }
207}
208
209fn generate_picklist_status_mapping(status_ident: &syn::Ident) -> TokenStream {
216 quote! {
217 {
218 use iced::widget::pick_list::Status;
219 match #status_ident {
220 Status::Active => None,
221 Status::Hovered => Some(dampen_core::ir::WidgetState::Hover),
222 Status::Opened { .. } => Some(dampen_core::ir::WidgetState::Focus),
223 }
224 }
225 }
226}
227
228fn generate_combo_box_status_mapping(status_ident: &syn::Ident) -> TokenStream {
232 generate_text_input_status_mapping(status_ident)
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238 use quote::format_ident;
239
240 #[test]
241 fn test_button_status_mapping_generated() {
242 let status = format_ident!("status");
243 let mapping = generate_status_mapping(&WidgetKind::Button, &status);
244 assert!(mapping.is_some());
245
246 let code = mapping.unwrap().to_string();
247 assert!(code.contains("Active"));
249 assert!(code.contains("Hovered"));
250 assert!(code.contains("Pressed"));
251 assert!(code.contains("Disabled"));
252 assert!(code.contains("WidgetState"));
253 }
254
255 #[test]
256 fn test_text_input_status_mapping_generated() {
257 let status = format_ident!("status");
258 let mapping = generate_status_mapping(&WidgetKind::TextInput, &status);
259 assert!(mapping.is_some());
260
261 let code = mapping.unwrap().to_string();
262 assert!(code.contains("Focused"));
263 assert!(code.contains("WidgetState"));
264 }
265
266 #[test]
267 fn test_checkbox_status_mapping_generated() {
268 let status = format_ident!("status");
269 let mapping = generate_status_mapping(&WidgetKind::Checkbox, &status);
270 assert!(mapping.is_some());
271
272 let code = mapping.unwrap().to_string();
273 assert!(code.contains("Active"));
274 assert!(code.contains("Hovered"));
275 assert!(code.contains("WidgetState"));
276 }
277
278 #[test]
279 fn test_unsupported_widget_returns_none() {
280 let status = format_ident!("status");
281 let mapping = generate_status_mapping(&WidgetKind::Text, &status);
282 assert!(mapping.is_none());
283 }
284
285 #[test]
286 fn test_slider_status_mapping_generated() {
287 let status = format_ident!("status");
288 let mapping = generate_status_mapping(&WidgetKind::Slider, &status);
289 assert!(mapping.is_some());
290
291 let code = mapping.unwrap().to_string();
292 assert!(code.contains("Dragged"));
293 assert!(code.contains("WidgetState"));
294 }
295
296 #[test]
297 fn test_combo_box_uses_text_input_mapping() {
298 let status = format_ident!("status");
299 let combo_mapping = generate_status_mapping(&WidgetKind::ComboBox, &status);
300 let text_mapping = generate_status_mapping(&WidgetKind::TextInput, &status);
301
302 assert!(combo_mapping.is_some());
303 assert!(text_mapping.is_some());
304
305 let combo_code = combo_mapping.unwrap().to_string();
307 let text_code = text_mapping.unwrap().to_string();
308 assert_eq!(combo_code, text_code);
309 }
310}