From d20493c8a0cc6e2e250434ed4cb6f350ed39d7e8 Mon Sep 17 00:00:00 2001 From: Marien Zwart Date: Sun, 21 May 2023 23:41:26 +1000 Subject: Support conversion from Fn trait to custom theme ...instead of just from function pointers. I'm making this change not because I actually want to pass a closure, but to make passing a single fixed function work. This commit also simplifies the scrollable example slightly, and without the other half of this change that simplified example fails to compile with: ``` error[E0277]: the trait bound `iced::theme::ProgressBar: From fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not satisfied --> examples/scrollable/src/main.rs:292:28 | 292 | .style(progress_bar_custom_style) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}>` is not implemented for `iced::theme::ProgressBar` | | | required by a bound introduced by this call | = help: the trait `From fn(&'a Theme) -> iced::widget::progress_bar::Appearance>` is implemented for `iced::theme::ProgressBar` = note: required for `for<'a> fn(&'a Theme) -> iced::widget::progress_bar::Appearance {progress_bar_custom_style}` to implement `Into` note: required by a bound in `iced::widget::ProgressBar::::style` --> /home/marienz/src/iced/widget/src/progress_bar.rs:77:21 | 77 | style: impl Into<::Style>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProgressBar::::style` ``` This happens because `progress_bar_custom_style` by itself is a function item, which is typically coerced to a function pointer when one is needed, but not in this case. It is possible to work around this on the caller's side, but especially since the compiler diagnostic for this is a bit rough (see https://github.com/rust-lang/rust/issues/100116) let's try to make it work out of the box. --- style/src/theme.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'style/src') diff --git a/style/src/theme.rs b/style/src/theme.rs index 6299975d..9500fe9d 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -105,7 +105,7 @@ impl application::StyleSheet for Theme { } } -impl application::StyleSheet for fn(&Theme) -> application::Appearance { +impl application::Appearance> application::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> application::Appearance { @@ -113,8 +113,10 @@ impl application::StyleSheet for fn(&Theme) -> application::Appearance { } } -impl From application::Appearance> for Application { - fn from(f: fn(&Theme) -> application::Appearance) -> Self { +impl application::Appearance + 'static> From + for Application +{ + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -363,8 +365,8 @@ pub enum Container { Custom(Box>), } -impl From container::Appearance> for Container { - fn from(f: fn(&Theme) -> container::Appearance) -> Self { +impl container::Appearance + 'static> From for Container { + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -391,7 +393,7 @@ impl container::StyleSheet for Theme { } } -impl container::StyleSheet for fn(&Theme) -> container::Appearance { +impl container::Appearance> container::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> container::Appearance { @@ -777,8 +779,10 @@ pub enum ProgressBar { Custom(Box>), } -impl From progress_bar::Appearance> for ProgressBar { - fn from(f: fn(&Theme) -> progress_bar::Appearance) -> Self { +impl progress_bar::Appearance + 'static> From + for ProgressBar +{ + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -808,7 +812,7 @@ impl progress_bar::StyleSheet for Theme { } } -impl progress_bar::StyleSheet for fn(&Theme) -> progress_bar::Appearance { +impl progress_bar::Appearance> progress_bar::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> progress_bar::Appearance { @@ -826,8 +830,8 @@ pub enum Rule { Custom(Box>), } -impl From rule::Appearance> for Rule { - fn from(f: fn(&Theme) -> rule::Appearance) -> Self { +impl rule::Appearance + 'static> From for Rule { + fn from(f: T) -> Self { Self::Custom(Box::new(f)) } } @@ -850,7 +854,7 @@ impl rule::StyleSheet for Theme { } } -impl rule::StyleSheet for fn(&Theme) -> rule::Appearance { +impl rule::Appearance> rule::StyleSheet for T { type Style = Theme; fn appearance(&self, style: &Self::Style) -> rule::Appearance { -- cgit