Skip to main content

ferroui_view/
conversions.rs

1//! The conversions that keep setters short: what a setter of a property
2//! takes besides the value of the property itself (see
3//! [`IntoValue`](crate::builder::IntoValue)).
4//!
5//! | given                         | property value                     |
6//! |-------------------------------|------------------------------------|
7//! | `T`                           | `Option<T>`                        |
8//! | `&str`, `&String`             | `String`, `Option<String>`         |
9//! | an integer, `f64`             | `Option<String>` (its text)        |
10//! | an integer, `f32`             | `f64`                              |
11//! | `f64`, `(f64, f64)`, `(f64, f64, f64, f64)` | `Thickness`          |
12//! | `f64`                         | `CornerRadius`                     |
13//! | `Color`, a color name or `#rgb` text | `Option<Rc<dyn IBrush>>`    |
14//! | `&str`                        | `Option<BoxedValue>` (text content)|
15//!
16//! A color text that does not parse panics with the text: it is a mistake
17//! in the source, like an attribute XAML does not compile.
18
19use crate::builder::{FromValue, IntoValue};
20use ferroui_base::media::immutable::ImmutableSolidColorBrush;
21use ferroui_base::media::{Brush, Color, IBrush};
22use ferroui_base::{BoxedValue, CornerRadius, PropertyValue, Thickness};
23use std::rc::Rc;
24
25impl<T: PropertyValue> IntoValue<Option<T>> for T {
26    fn into_value(self) -> Option<T> {
27        Some(self)
28    }
29}
30
31impl<T: Clone> FromValue<Option<T>> for T {
32    fn from_value(value: &Option<T>) -> Option<Self> {
33        value.clone()
34    }
35}
36
37impl IntoValue<String> for &str {
38    fn into_value(self) -> String {
39        self.to_string()
40    }
41}
42
43impl IntoValue<Option<String>> for &str {
44    fn into_value(self) -> Option<String> {
45        Some(self.to_string())
46    }
47}
48
49impl IntoValue<Option<String>> for &String {
50    fn into_value(self) -> Option<String> {
51        Some(self.clone())
52    }
53}
54
55impl IntoValue<Option<BoxedValue>> for &str {
56    fn into_value(self) -> Option<BoxedValue> {
57        Some(Rc::new(self.to_string()))
58    }
59}
60
61impl IntoValue<Option<BoxedValue>> for String {
62    fn into_value(self) -> Option<BoxedValue> {
63        Some(Rc::new(self))
64    }
65}
66
67macro_rules! number_to_text {
68    ($($t:ty),*) => {$(
69        impl IntoValue<Option<String>> for $t {
70            fn into_value(self) -> Option<String> {
71                Some(self.to_string())
72            }
73        }
74        impl IntoValue<Option<BoxedValue>> for $t {
75            fn into_value(self) -> Option<BoxedValue> {
76                Some(Rc::new(self.to_string()))
77            }
78        }
79    )*};
80}
81
82number_to_text!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, f32, f64);
83
84macro_rules! number_to_f64 {
85    ($($t:ty),*) => {$(
86        impl IntoValue<f64> for $t {
87            fn into_value(self) -> f64 {
88                f64::from(self)
89            }
90        }
91    )*};
92}
93
94number_to_f64!(i8, i16, i32, u8, u16, u32, f32);
95
96impl IntoValue<Thickness> for f64 {
97    fn into_value(self) -> Thickness {
98        Thickness::uniform(self)
99    }
100}
101
102impl IntoValue<Thickness> for i32 {
103    fn into_value(self) -> Thickness {
104        Thickness::uniform(f64::from(self))
105    }
106}
107
108impl IntoValue<Thickness> for (f64, f64) {
109    fn into_value(self) -> Thickness {
110        Thickness::symmetric(self.0, self.1)
111    }
112}
113
114impl IntoValue<Thickness> for (f64, f64, f64, f64) {
115    fn into_value(self) -> Thickness {
116        Thickness::new(self.0, self.1, self.2, self.3)
117    }
118}
119
120impl IntoValue<CornerRadius> for f64 {
121    fn into_value(self) -> CornerRadius {
122        CornerRadius::uniform(self)
123    }
124}
125
126impl IntoValue<CornerRadius> for i32 {
127    fn into_value(self) -> CornerRadius {
128        CornerRadius::uniform(f64::from(self))
129    }
130}
131
132impl IntoValue<Option<Rc<dyn IBrush>>> for Color {
133    fn into_value(self) -> Option<Rc<dyn IBrush>> {
134        Some(Rc::new(ImmutableSolidColorBrush::new(self)))
135    }
136}
137
138impl IntoValue<Option<Rc<dyn IBrush>>> for &str {
139    fn into_value(self) -> Option<Rc<dyn IBrush>> {
140        Some(Brush::parse(self).unwrap_or_else(|_| panic!("`{self}` is not a color")))
141    }
142}