diff options
author | qkzk <qu3nt1n@gmail.com> | 2022-12-21 00:30:00 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2022-12-21 00:32:38 +0100 |
commit | c02d7a5fd8eaaf183c7a4afee6d2503deb146812 (patch) | |
tree | 2f45005d3f36578c5f57b0467874486aaf6cc495 /src/selectable_content.rs | |
parent | c10b023eeac815039a4e4e2cbf813b422f20ef6a (diff) |
fix wrong navigation order. Rename everything to selectable content
Diffstat (limited to 'src/selectable_content.rs')
-rw-r--r-- | src/selectable_content.rs | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/selectable_content.rs b/src/selectable_content.rs new file mode 100644 index 0000000..4669e70 --- /dev/null +++ b/src/selectable_content.rs @@ -0,0 +1,66 @@ +/// Make a content selectable content for a struct. +/// This trait allows to navigate through a vector of element `content_type`. +/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`. +/// `selected` returns an optional reference to the value. +pub trait SelectableContent<T> { + fn is_empty(&self) -> bool; + fn len(&self) -> usize; + fn next(&mut self); + fn prev(&mut self); + fn selected(&self) -> Option<&T>; +} + +/// Implement the `SelectableContent` for struct `$struc` with content type `$content_type`. +/// This trait allows to navigate through a vector of element `content_type`. +/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`. +/// `selected` returns an optional reference to the value. +#[macro_export] +macro_rules! impl_selectable_content { + ($content_type:ident, $struct:ident) => { + use $crate::selectable_content::SelectableContent; + + /// Implement a selectable content for this struct. + /// This trait allows to navigate through a vector of element `content_type`. + /// It implements: `is_empty`, `len`, `next`, `prev`, `selected`. + /// `selected` returns an optional reference to the value. + impl SelectableContent<$content_type> for $struct { + /// True if the content is empty. + fn is_empty(&self) -> bool { + self.content.is_empty() + } + + /// The size of the content. + fn len(&self) -> usize { + self.content.len() + } + + /// Select the prev item. + fn prev(&mut self) { + if self.is_empty() { + self.index = 0 + } else if self.index > 0 { + self.index -= 1; + } else { + self.index = self.len() - 1 + } + } + + /// Select the next item. + fn next(&mut self) { + if self.is_empty() { + self.index = 0; + } else { + self.index = (self.index + 1) % self.len() + } + } + + /// Returns a reference to the selected content. + fn selected(&self) -> Option<&$content_type> { + match self.is_empty() { + true => None, + false => Some(&self.content[self.index]), + } + } + } + }; +} |