Skip to main content

use_affordance/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// UI affordance vocabulary.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
6pub enum Affordance {
7    Clickable,
8    Draggable,
9    Selectable,
10    Expandable,
11    Dismissible,
12    Resizable,
13    Scrollable,
14    Editable,
15    Sortable,
16    Navigable,
17}
18
19/// A small affordance collection with duplicate prevention.
20#[derive(Debug, Clone, Default, PartialEq, Eq)]
21pub struct AffordanceSet {
22    affordances: Vec<Affordance>,
23}
24
25impl AffordanceSet {
26    pub fn new(affordances: Vec<Affordance>) -> Self {
27        let mut set = Self::default();
28        for affordance in affordances {
29            set.insert(affordance);
30        }
31        set
32    }
33
34    pub fn insert(&mut self, affordance: Affordance) {
35        if !self.contains(affordance) {
36            self.affordances.push(affordance);
37        }
38    }
39
40    pub fn contains(&self, affordance: Affordance) -> bool {
41        self.affordances.contains(&affordance)
42    }
43
44    pub fn affordances(&self) -> &[Affordance] {
45        &self.affordances
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::{Affordance, AffordanceSet};
52
53    #[test]
54    fn checks_affordance_set_membership() {
55        let mut set = AffordanceSet::new(vec![Affordance::Clickable, Affordance::Expandable]);
56        set.insert(Affordance::Clickable);
57        set.insert(Affordance::Dismissible);
58
59        assert!(set.contains(Affordance::Clickable));
60        assert!(set.contains(Affordance::Dismissible));
61        assert!(!set.contains(Affordance::Sortable));
62        assert_eq!(set.affordances().len(), 3);
63    }
64}