1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
/// 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>;
fn index(&self) -> usize;
fn content(&self) -> &Vec<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]),
}
}
/// Returns the index of the selected item.
fn index(&self) -> usize {
self.index
}
/// A reference to the content.
fn content(&self) -> &Vec<$content_type> {
&self.content
}
}
};
}