summaryrefslogtreecommitdiffstats
path: root/src/selectable_content.rs
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2022-12-21 00:30:00 +0100
committerqkzk <qu3nt1n@gmail.com>2022-12-21 00:32:38 +0100
commitc02d7a5fd8eaaf183c7a4afee6d2503deb146812 (patch)
tree2f45005d3f36578c5f57b0467874486aaf6cc495 /src/selectable_content.rs
parentc10b023eeac815039a4e4e2cbf813b422f20ef6a (diff)
fix wrong navigation order. Rename everything to selectable content
Diffstat (limited to 'src/selectable_content.rs')
-rw-r--r--src/selectable_content.rs66
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]),
+ }
+ }
+ }
+ };
+}