From f53cfb8efa81563b76a4b585ae8cd856dd1eb149 Mon Sep 17 00:00:00 2001
From: Héctor Ramón Jiménez <hector@hecrj.dev>
Date: Wed, 14 Feb 2024 03:54:40 +0100
Subject: Use `Borrow` for both `options` and `selected` in `PickList`

---
 examples/layout/src/main.rs  |  6 +----
 examples/qr_code/src/main.rs |  6 +----
 examples/styling/src/main.rs |  8 ++----
 widget/src/helpers.rs        | 15 +++++------
 widget/src/pick_list.rs      | 59 +++++++++++++++++++++++++-------------------
 5 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs
index b626c70d..f41c9986 100644
--- a/examples/layout/src/main.rs
+++ b/examples/layout/src/main.rs
@@ -88,11 +88,7 @@ impl Application for Layout {
             horizontal_space(Length::Fill),
             checkbox("Explain", self.explain)
                 .on_toggle(Message::ExplainToggled),
-            pick_list(
-                Theme::ALL,
-                Some(self.theme.clone()),
-                Message::ThemeSelected
-            ),
+            pick_list(Theme::ALL, Some(&self.theme), Message::ThemeSelected),
         ]
         .spacing(20)
         .align_items(Alignment::Center);
diff --git a/examples/qr_code/src/main.rs b/examples/qr_code/src/main.rs
index 8b2e9500..9f75eaf6 100644
--- a/examples/qr_code/src/main.rs
+++ b/examples/qr_code/src/main.rs
@@ -60,11 +60,7 @@ impl Sandbox for QRGenerator {
 
         let choose_theme = row![
             text("Theme:"),
-            pick_list(
-                Theme::ALL,
-                Some(self.theme.clone()),
-                Message::ThemeChanged,
-            )
+            pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged,)
         ]
         .spacing(10)
         .align_items(Alignment::Center);
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs
index cf2dcb8a..c26215b6 100644
--- a/examples/styling/src/main.rs
+++ b/examples/styling/src/main.rs
@@ -55,12 +55,8 @@ impl Sandbox for Styling {
     fn view(&self) -> Element<Message> {
         let choose_theme = column![
             text("Theme:"),
-            pick_list(
-                Theme::ALL,
-                Some(self.theme.clone()),
-                Message::ThemeChanged
-            )
-            .width(Length::Fill),
+            pick_list(Theme::ALL, Some(&self.theme), Message::ThemeChanged)
+                .width(Length::Fill),
         ]
         .spacing(10);
 
diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs
index a5411c89..e9898d67 100644
--- a/widget/src/helpers.rs
+++ b/widget/src/helpers.rs
@@ -22,7 +22,7 @@ use crate::toggler::{self, Toggler};
 use crate::tooltip::{self, Tooltip};
 use crate::{Column, MouseArea, Row, Space, Themer, VerticalSlider};
 
-use std::borrow::Cow;
+use std::borrow::Borrow;
 use std::ops::RangeInclusive;
 
 /// Creates a [`Column`] with the given children.
@@ -264,14 +264,15 @@ where
 /// Creates a new [`PickList`].
 ///
 /// [`PickList`]: crate::PickList
-pub fn pick_list<'a, Message, Theme, Renderer, T>(
-    options: impl Into<Cow<'a, [T]>>,
-    selected: Option<T>,
+pub fn pick_list<'a, T, L, V, Message, Theme, Renderer>(
+    options: L,
+    selected: Option<V>,
     on_selected: impl Fn(T) -> Message + 'a,
-) -> PickList<'a, T, Message, Theme, Renderer>
+) -> PickList<'a, T, L, V, Message, Theme, Renderer>
 where
-    T: ToString + PartialEq + 'static,
-    [T]: ToOwned<Owned = Vec<T>>,
+    T: ToString + PartialEq + Clone + 'a,
+    L: Borrow<[T]> + 'a,
+    V: Borrow<T> + 'a,
     Message: Clone,
     Renderer: core::text::Renderer,
     Theme: pick_list::StyleSheet
diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs
index 840c94fa..1f20e2bc 100644
--- a/widget/src/pick_list.rs
+++ b/widget/src/pick_list.rs
@@ -17,7 +17,7 @@ use crate::core::{
 use crate::overlay::menu::{self, Menu};
 use crate::scrollable;
 
-use std::borrow::Cow;
+use std::borrow::Borrow;
 
 pub use crate::style::pick_list::{Appearance, StyleSheet};
 
@@ -26,20 +26,24 @@ pub use crate::style::pick_list::{Appearance, StyleSheet};
 pub struct PickList<
     'a,
     T,
+    L,
+    V,
     Message,
     Theme = crate::Theme,
     Renderer = crate::Renderer,
 > where
-    [T]: ToOwned<Owned = Vec<T>>,
+    T: ToString + PartialEq + Clone,
+    L: Borrow<[T]> + 'a,
+    V: Borrow<T> + 'a,
     Theme: StyleSheet,
     Renderer: text::Renderer,
 {
     on_select: Box<dyn Fn(T) -> Message + 'a>,
     on_open: Option<Message>,
     on_close: Option<Message>,
-    options: Cow<'a, [T]>,
+    options: L,
     placeholder: Option<String>,
-    selected: Option<T>,
+    selected: Option<V>,
     width: Length,
     padding: Padding,
     text_size: Option<Pixels>,
@@ -50,11 +54,12 @@ pub struct PickList<
     style: Theme::Style,
 }
 
-impl<'a, T: 'a, Message, Theme, Renderer>
-    PickList<'a, T, Message, Theme, Renderer>
+impl<'a, T, L, V, Message, Theme, Renderer>
+    PickList<'a, T, L, V, Message, Theme, Renderer>
 where
-    T: ToString + PartialEq,
-    [T]: ToOwned<Owned = Vec<T>>,
+    T: ToString + PartialEq + Clone,
+    L: Borrow<[T]> + 'a,
+    V: Borrow<T> + 'a,
     Message: Clone,
     Theme: StyleSheet
         + scrollable::StyleSheet
@@ -69,15 +74,15 @@ where
     /// Creates a new [`PickList`] with the given list of options, the current
     /// selected value, and the message to produce when an option is selected.
     pub fn new(
-        options: impl Into<Cow<'a, [T]>>,
-        selected: Option<T>,
+        options: L,
+        selected: Option<V>,
         on_select: impl Fn(T) -> Message + 'a,
     ) -> Self {
         Self {
             on_select: Box::new(on_select),
             on_open: None,
             on_close: None,
-            options: options.into(),
+            options,
             placeholder: None,
             selected,
             width: Length::Shrink,
@@ -164,11 +169,12 @@ where
     }
 }
 
-impl<'a, T: 'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
-    for PickList<'a, T, Message, Theme, Renderer>
+impl<'a, T, L, V, Message, Theme, Renderer> Widget<Message, Theme, Renderer>
+    for PickList<'a, T, L, V, Message, Theme, Renderer>
 where
-    T: Clone + ToString + PartialEq + 'static,
-    [T]: ToOwned<Owned = Vec<T>>,
+    T: Clone + ToString + PartialEq + 'a,
+    L: Borrow<[T]>,
+    V: Borrow<T>,
     Message: Clone + 'a,
     Theme: StyleSheet
         + scrollable::StyleSheet
@@ -209,7 +215,7 @@ where
             self.text_shaping,
             self.font,
             self.placeholder.as_deref(),
-            &self.options,
+            self.options.borrow(),
         )
     }
 
@@ -232,8 +238,8 @@ where
             self.on_select.as_ref(),
             self.on_open.as_ref(),
             self.on_close.as_ref(),
-            self.selected.as_ref(),
-            &self.options,
+            self.selected.as_ref().map(Borrow::borrow),
+            self.options.borrow(),
             || tree.state.downcast_mut::<State<Renderer::Paragraph>>(),
         )
     }
@@ -271,7 +277,7 @@ where
             self.text_shaping,
             font,
             self.placeholder.as_deref(),
-            self.selected.as_ref(),
+            self.selected.as_ref().map(Borrow::borrow),
             &self.handle,
             &self.style,
             || tree.state.downcast_ref::<State<Renderer::Paragraph>>(),
@@ -296,19 +302,20 @@ where
             self.text_size,
             self.text_shaping,
             self.font.unwrap_or_else(|| renderer.default_font()),
-            &self.options,
+            self.options.borrow(),
             &self.on_select,
             self.style.clone(),
         )
     }
 }
 
-impl<'a, T: 'a, Message, Theme, Renderer>
-    From<PickList<'a, T, Message, Theme, Renderer>>
+impl<'a, T, L, V, Message, Theme, Renderer>
+    From<PickList<'a, T, L, V, Message, Theme, Renderer>>
     for Element<'a, Message, Theme, Renderer>
 where
-    T: Clone + ToString + PartialEq + 'static,
-    [T]: ToOwned<Owned = Vec<T>>,
+    T: Clone + ToString + PartialEq + 'a,
+    L: Borrow<[T]> + 'a,
+    V: Borrow<T> + 'a,
     Message: Clone + 'a,
     Theme: StyleSheet
         + scrollable::StyleSheet
@@ -318,7 +325,9 @@ where
     <Theme as menu::StyleSheet>::Style: From<<Theme as StyleSheet>::Style>,
     Renderer: text::Renderer + 'a,
 {
-    fn from(pick_list: PickList<'a, T, Message, Theme, Renderer>) -> Self {
+    fn from(
+        pick_list: PickList<'a, T, L, V, Message, Theme, Renderer>,
+    ) -> Self {
         Self::new(pick_list)
     }
 }
-- 
cgit