free_launch/
selectable.rs1use 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 pub fn new(value: T) -> Self {
24 Self::Existing {
25 value,
26 selected: false.into(),
27 }
28 }
29
30 pub fn new_selected(value: T) -> Self {
32 Self::Existing {
33 value,
34 selected: true.into(),
35 }
36 }
37
38 pub fn new_requested(value: String) -> Self {
40 Self::Requested {
41 value,
42 selected: false.into(),
43 }
44 }
45
46 pub fn new_requested_selected(value: String) -> Self {
48 Self::Requested {
49 value,
50 selected: true.into(),
51 }
52 }
53
54 pub fn value(&self) -> Option<&T> {
56 match self {
57 SelectableItem::Existing { value, .. } => Some(value),
58 SelectableItem::Requested { .. } => None,
59 }
60 }
61
62 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 pub fn requested_value(&self) -> Option<&String> {
72 match self {
73 SelectableItem::Existing { .. } => None,
74 SelectableItem::Requested { value, .. } => Some(value),
75 }
76 }
77
78 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 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 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 pub fn into_inner(self) -> Option<T> {
112 match self {
113 SelectableItem::Existing { value, .. } => Some(value),
114 SelectableItem::Requested { .. } => None,
115 }
116 }
117
118 pub fn is_existing(&self) -> bool {
120 matches!(self, SelectableItem::Existing { .. })
121 }
122
123 pub fn is_requested(&self) -> bool {
125 matches!(self, SelectableItem::Requested { .. })
126 }
127}