use iced::Element; use super::{Action, Message, Navigation}; pub fn update_navigation<'a, TOption>( navigation: &mut Navigation, message: Message, ) -> Action where TOption: Clone + PartialEq + Into>>, { match message { Message::SelectOption(option) => { if navigation .active_option .as_ref() .is_some_and(|active_option| active_option.clone() == option) { Action::None } else if let Some(index) = navigation .options_before_active .iter() .position(|o| o.clone() == option) { let split = navigation.options_before_active.split_at(index); navigation.options_after_active = vec![ navigation .active_option .clone() .map_or(vec![], |active_option| vec![active_option]), split.1.split_at(1).1.to_vec(), navigation.options_after_active.clone(), ] .concat(); navigation.options_before_active = split.0.to_vec(); navigation.active_option = Some(option.clone()); Action::SelectOption(option) } else if let Some(index) = navigation .options_after_active .iter() .position(|o| o.clone() == option) { let split = navigation.options_after_active.split_at(index); navigation.options_before_active = vec![ navigation.options_before_active.clone(), split.0.to_vec(), navigation .active_option .clone() .map_or(vec![], |active_option| vec![active_option]), ] .concat(); navigation.active_option = Some(option.clone()); navigation.options_after_active = split.1.split_at(1).1.to_vec(); Action::SelectOption(option) } else { if let Some(active_option) = &navigation.active_option { navigation.options_before_active.push(active_option.clone()); } navigation .options_before_active .append(&mut navigation.options_after_active); navigation.active_option = Some(option.clone()); navigation.options_after_active = vec![]; Action::SelectOption(option) } } Message::SetOptions(options) => { let active_option_index = navigation .active_option .clone() .map_or(Option::None, |active_option| { options .iter() .position(|option| active_option == option.clone()) }); if let Some(active_option_index) = active_option_index { let split = options.split_at(active_option_index); navigation.options_before_active = split.0.to_vec(); navigation.options_after_active = split.1.split_at(1).1.to_vec(); Action::None } else { navigation.options_before_active = options .split_last() .map_or_else(Vec::new, |(_last, rest)| rest.to_vec()); navigation.active_option = options.last().cloned(); options .last() .cloned() .map_or(Action::None, Action::SelectOption) } } Message::SelectNext => { if let Some(next) = navigation.options_after_active.clone().first() { navigation.options_before_active = vec![ navigation.options_before_active.clone(), navigation.active_option.clone().map_or(vec![], |o| vec![o]), ] .concat(); navigation.active_option = Some(next.clone()); navigation.options_after_active = navigation.options_after_active.split_at(1).1.to_vec(); Action::SelectOption(next.clone()) } else { Action::None } } Message::SelectPrev => { if let Some(prev) = navigation.options_before_active.clone().last() { navigation.options_after_active = vec![ navigation.active_option.clone().map_or(vec![], |o| vec![o]), navigation.options_after_active.clone(), ] .concat(); navigation.active_option = Some(prev.clone()); navigation.options_before_active = navigation .options_before_active .split_last() .map(|split| split.1.to_vec()) .unwrap_or_else(Vec::new); Action::SelectOption(prev.clone()) } else { Action::None } } } }