use std::fmt::Debug; use std::path::Path; use Default::default; use dsb::Cell; use crate::menu::{Key, back, filter, next, score}; use crate::text::TextArea; pub struct GenericMenu { pub data: T::Data, pub tedit: TextArea, pub selection: usize, pub vo: usize, } impl> Clone for GenericMenu { fn clone(&self) -> Self { Self { data: self.data.clone(), tedit: self.tedit.clone(), selection: self.selection.clone(), vo: self.vo.clone(), } } } impl> Default for GenericMenu { fn default() -> Self { Self { data: default(), tedit: default(), selection: default(), vo: default(), } } } impl> Debug for GenericMenu { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct(&format!( "GenericMenu<{}>", std::any::type_name::() )) .field("data", &self.data) .field("tedit", &self.tedit) .field("selection", &self.selection) .field("vo", &self.vo) .finish() } } pub trait MenuData { const HEIGHT: usize = 30; type Data; type Element<'a>: Key<'a>; fn gn<'a>( x: &'a Self::Data, ) -> impl Iterator>; fn r( data: &'_ Self::Data, elem: Self::Element<'_>, workspace: &Path, columns: usize, selected: bool, indices: &[u32], to: &mut Vec, ); fn filter_c<'a>( x: &'a Self::Data, f: &str, ) -> impl Iterator> { filter(Self::gn(x), f) } fn score_c<'a>( x: impl Iterator>, f: &str, ) -> Vec<(u32, Self::Element<'a>, Vec)> { score(x, f) } } impl GenericMenu { fn f(&self) -> String { self.tedit.rope.to_string() } pub fn next(&mut self) where [(); T::HEIGHT]:, { let n = T::filter_c(&self.data, &self.f()).count(); // coz its bottom up back::<{ T::HEIGHT }>(n, &mut self.selection, &mut self.vo); } pub fn sel(&self) -> T::Element<'_> { let f = self.f(); T::score_c(T::filter_c(&self.data, &f), &f) .swap_remove(self.selection) .1 } pub fn back(&mut self) where [(); T::HEIGHT]:, { let n = T::filter_c(&self.data, &self.f()).count(); next::<{ T::HEIGHT }>(n, &mut self.selection, &mut self.vo); } pub fn cells(&self, c: usize, ws: &Path) -> Vec { let f = self.f(); let mut out = vec![]; let v = T::score_c(T::filter_c(&self.data, &f), &f); let vlen = v.len(); let i = v.into_iter().zip(0..vlen).skip(self.vo).take(T::HEIGHT).rev(); i.for_each(|((_, x, indices), i)| { T::r( &self.data, x, ws, c, i == self.selection, &indices, &mut out, ) }); out } }