Implement Menu::map naively

This commit is contained in:
Héctor Ramón Jiménez 2021-07-19 20:59:09 +07:00
parent 2e7eac7d21
commit 3099f36100
No known key found for this signature in database
GPG key ID: 140CC052C94F138E

View file

@ -26,15 +26,30 @@ impl<Message> Menu<Message> {
Self { entries }
}
/// Returns a [`MenuEntry`] iterator.
pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> {
self.entries.iter()
}
/// Adds an [`Entry`] to the [`Menu`].
pub fn push(mut self, entry: Entry<Message>) -> Self {
self.entries.push(entry);
self
}
/// Returns a [`MenuEntry`] iterator.
pub fn iter(&self) -> impl Iterator<Item = &Entry<Message>> {
self.entries.iter()
/// Maps the `Message` of the [`Menu`] using the provided function.
///
/// This is useful to compose menus and split them into different
/// abstraction levels.
pub fn map<B>(self, f: &impl Fn(Message) -> B) -> Menu<B> {
// TODO: Use a boxed trait to avoid reallocation of entries
Menu {
entries: self
.entries
.into_iter()
.map(|entry| entry.map(f))
.collect(),
}
}
}
@ -71,7 +86,7 @@ impl<Message> Entry<Message> {
let content = content.into();
let hotkey = hotkey.into();
Entry::Item {
Self::Item {
content,
hotkey,
on_activation,
@ -85,7 +100,26 @@ impl<Message> Entry<Message> {
) -> Self {
let content = content.into();
Entry::Dropdown { content, submenu }
Self::Dropdown { content, submenu }
}
fn map<B>(self, f: &impl Fn(Message) -> B) -> Entry<B> {
match self {
Self::Item {
content,
hotkey,
on_activation,
} => Entry::Item {
content,
hotkey,
on_activation: f(on_activation),
},
Self::Dropdown { content, submenu } => Entry::Dropdown {
content,
submenu: submenu.map(f),
},
Self::Separator => Entry::Separator,
}
}
}