free_launch/
selectable.rs

1use std::{
2    fmt::Display,
3    sync::atomic::{AtomicBool, Ordering},
4};
5
6#[derive(Debug)]
7pub enum SelectableItem<T> {
8    Existing { value: T, selected: AtomicBool },
9    Requested { value: String, selected: AtomicBool },
10}
11
12impl<T: Display> Display for SelectableItem<T> {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        match self {
15            SelectableItem::Existing { value, .. } => write!(f, "{}", value),
16            SelectableItem::Requested { value, .. } => write!(f, "{}", value),
17        }
18    }
19}
20
21impl<T> SelectableItem<T> {
22    // Create a new unselected Existing instance
23    pub fn new(value: T) -> Self {
24        Self::Existing {
25            value,
26            selected: false.into(),
27        }
28    }
29
30    // Create a new selected Existing instance
31    pub fn new_selected(value: T) -> Self {
32        Self::Existing {
33            value,
34            selected: true.into(),
35        }
36    }
37
38    // Create a new unselected Requested instance
39    pub fn new_requested(value: String) -> Self {
40        Self::Requested {
41            value,
42            selected: false.into(),
43        }
44    }
45
46    // Create a new selected Requested instance
47    pub fn new_requested_selected(value: String) -> Self {
48        Self::Requested {
49            value,
50            selected: true.into(),
51        }
52    }
53
54    // Get a reference to the inner value (only for Existing variant)
55    pub fn value(&self) -> Option<&T> {
56        match self {
57            SelectableItem::Existing { value, .. } => Some(value),
58            SelectableItem::Requested { .. } => None,
59        }
60    }
61
62    // Get a mutable reference to the inner value (only for Existing variant)
63    pub fn value_mut(&mut self) -> Option<&mut T> {
64        match self {
65            SelectableItem::Existing { value, .. } => Some(value),
66            SelectableItem::Requested { .. } => None,
67        }
68    }
69
70    // Get a reference to the string value (only for Requested variant)
71    pub fn requested_value(&self) -> Option<&String> {
72        match self {
73            SelectableItem::Existing { .. } => None,
74            SelectableItem::Requested { value, .. } => Some(value),
75        }
76    }
77
78    // Get the selected state
79    pub fn is_selected(&self) -> bool {
80        match self {
81            SelectableItem::Existing { selected, .. } => selected.load(Ordering::SeqCst),
82            SelectableItem::Requested { selected, .. } => selected.load(Ordering::SeqCst),
83        }
84    }
85
86    // Set the selected state
87    pub fn set_selected(&self, selected_state: bool) {
88        match self {
89            SelectableItem::Existing { selected, .. } => {
90                selected.store(selected_state, Ordering::SeqCst)
91            }
92            SelectableItem::Requested { selected, .. } => {
93                selected.store(selected_state, Ordering::SeqCst)
94            }
95        }
96    }
97
98    // Toggle the selected state
99    pub fn toggle_selected(&self) {
100        match self {
101            SelectableItem::Existing { selected, .. } => {
102                selected.fetch_xor(true, Ordering::SeqCst);
103            }
104            SelectableItem::Requested { selected, .. } => {
105                selected.fetch_xor(true, Ordering::SeqCst);
106            }
107        }
108    }
109
110    // Consume the wrapper and return the inner value (only for Existing variant)
111    pub fn into_inner(self) -> Option<T> {
112        match self {
113            SelectableItem::Existing { value, .. } => Some(value),
114            SelectableItem::Requested { .. } => None,
115        }
116    }
117
118    // Check if this is an Existing variant
119    pub fn is_existing(&self) -> bool {
120        matches!(self, SelectableItem::Existing { .. })
121    }
122
123    // Check if this is a Requested variant
124    pub fn is_requested(&self) -> bool {
125        matches!(self, SelectableItem::Requested { .. })
126    }
127}