mod navigate_navigation; mod navigation_find; mod navigation_insert_options; mod navigation_remove_options; mod navigation_replace_options; mod navigation_select_option; mod navigation_set_options; mod update_navigation; mod view_navigation; mod view_navigation_button; #[cfg(test)] mod dummy_navigation_option; use std::fmt::Debug; pub use navigation_insert_options::InsertOptionResult; #[derive(Clone, Debug)] pub struct Navigation { options_before_active: Vec, pub active_option: Option, options_after_active: Vec, } #[derive(Clone, Debug, PartialEq)] pub enum Message { ActivateOption(TOption), SelectNext, SelectOption(TOption), SelectPrev, SetOptions(Vec), } pub enum Action { ActivateOption(TOption), SelectOption(TOption), None, } impl Navigation { pub fn new(active_option: Option, options: Vec) -> Self { let active_option_index = active_option.clone().map_or(Option::None, |active_option| { options.iter().position(|option| option.eq(&active_option)) }); 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(), active_option: active_option, options_after_active: split.1.split_at(1).1.to_vec(), } } else { Navigation { options_before_active: options, active_option: active_option, options_after_active: vec![], } } } } #[cfg(test)] mod test { use super::Navigation; #[test] fn when_active_option_at_start_of_options_then_finds_active_option() { let navigation = Navigation::new(Some(1), vec![1, 2, 3, 4, 5]); assert_eq!(Vec::::new(), navigation.options_before_active); assert_eq!(Some(1), navigation.active_option); assert_eq!(vec![2, 3, 4, 5], navigation.options_after_active); } #[test] fn when_active_option_in_middle_of_options_then_finds_active_option() { let navigation = Navigation::new(Some(3), vec![1, 2, 3, 4, 5]); assert_eq!(vec![1, 2], navigation.options_before_active); assert_eq!(Some(3), navigation.active_option); assert_eq!(vec![4, 5], navigation.options_after_active); } #[test] fn when_active_option_at_end_of_options_then_finds_active_option() { let navigation = Navigation::new(Some(5), vec![1, 2, 3, 4, 5]); assert_eq!(vec![1, 2, 3, 4], navigation.options_before_active); assert_eq!(Some(5), navigation.active_option); assert_eq!(Vec::::new(), navigation.options_after_active); } #[test] fn when_active_option_not_in_options_then_appends_active_option() { let navigation = Navigation::new(Some(6), vec![1, 2, 3, 4, 5]); assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active); assert_eq!(Some(6), navigation.active_option); assert_eq!(Vec::::new(), navigation.options_after_active); } #[test] fn when_no_active_option_then_all_options_are_before_active_option() { let navigation = Navigation::new(None, vec![1, 2, 3, 4, 5]); assert_eq!(vec![1, 2, 3, 4, 5], navigation.options_before_active); assert_eq!(None, navigation.active_option); assert_eq!(Vec::::new(), navigation.options_after_active); } }