use super::*; use std::iter::FromIterator; #[cfg(nightly)] type ListAbs = std::collections::LinkedList; #[cfg(not(nightly))] type ListAbs = Vec; #[derive(Debug)] pub struct TaskList { list: ListAbs<(usize, String)>, buffer: String, index: usize, } fn find(list: &ListAbs, mut fun: F) -> Option where F: FnMut(&T) -> bool { for (i,x) in (0..).zip(list.iter()) { if fun(x) { return Some(i); } } None } impl TaskList { /// Create a new tasklist pub fn new() -> Self { Self { list: ListAbs::new(), buffer: String::new(), index: 0, } } /// Number of tasks in the list pub fn len(&self) -> usize { self.list.len() } /// Push a new task string, and return its ID. pub fn push(&mut self, string: impl Into) -> usize { let idx = { self.index+=1; self.index }; #[cfg(nightly)] self.list.push_back((idx,string.into())); #[cfg(not(nightly))] self.list.push((idx,string.into())); self.recalc(); idx } /// Pop a task off the string, returns `true` if successful, `false` if wasn't found. pub fn pop(&mut self, idx: usize) -> bool { if let Some(idx) = find(&self.list, |&(i, _)| idx == i) { self.list.remove(idx); self.recalc(); true } else { false } } /// Clear the `TaskList` pub fn clear(&mut self) { self.list.clear(); self.buffer = String::default(); } /// As a single `str` pub fn as_str(&self) -> &str { &self.buffer[..] } fn recalc(&mut self) { #[cfg(nightly)] { self.buffer = self.list.iter().map(|(_, s)| s.as_str()).join(", "); } #[cfg(not(nightly))] { self.buffer = self.list.iter().map(|(_, s)| s.as_str()).join(", "); } } } impl AsRef for TaskList { #[inline] fn as_ref(&self) -> &str { self.as_str() } } impl FromIterator for TaskList where T: Into { fn from_iter>(iter: I) -> Self { let mut i=0usize; let mut this = Self { list: iter.into_iter().map(|x| ((i, x.into()), i+=1).0).collect(), buffer: Default::default(), index: 0, }; this.index = i; this.recalc(); this } }