1use rusistor::Resistor;
2
3#[derive(Debug, Default)]
4pub struct SpecsHistory {
5 history: Vec<(String, String, String)>,
6 idx: Option<usize>,
7}
8
9impl SpecsHistory {
10 pub fn prev(&mut self) {
11 if !self.history.is_empty() {
12 if let Some(idx) = self.idx {
13 self.idx = Some(idx.saturating_sub(1));
14 } else {
15 self.idx = Some(self.history.len() - 1)
16 }
17 }
18 }
19
20 pub fn next(&mut self) {
21 if !self.history.is_empty() {
22 if let Some(idx) = self.idx {
23 self.idx = Some(idx.saturating_add(1).min(self.history.len() - 1));
24 } else {
25 self.idx = None;
26 }
27 }
28 }
29
30 pub fn try_get(&self) -> Option<&(String, String, String)> {
31 if let Some(idx) = self.idx {
32 self.history.get(idx)
33 } else {
34 None
35 }
36 }
37
38 pub fn add(&mut self, specs: (String, String, String)) {
39 match self.history.last() {
40 Some(x) if *x == specs => (),
41 _ => self.history.push(specs),
42 }
43 }
44
45 pub fn clear_idx(&mut self) {
46 self.idx = None;
47 }
48}
49
50#[derive(Debug, Default, PartialEq)]
51pub enum InputFocus {
52 #[default]
53 Resistance,
54 Tolerance,
55 Tcr,
56}
57
58impl InputFocus {
59 pub fn next(&self) -> InputFocus {
60 match self {
61 InputFocus::Resistance => InputFocus::Tolerance,
62 InputFocus::Tolerance => InputFocus::Tcr,
63 InputFocus::Tcr => InputFocus::Resistance,
64 }
65 }
66
67 pub fn prev(&self) -> InputFocus {
68 match self {
69 InputFocus::Resistance => InputFocus::Tcr,
70 InputFocus::Tolerance => InputFocus::Resistance,
71 InputFocus::Tcr => InputFocus::Tolerance,
72 }
73 }
74}
75
76#[derive(Debug, Default, PartialEq)]
77pub enum SelectedTab {
78 #[default]
79 ColorCodesToSpecs,
80 SpecsToColorCodes,
81}
82
83impl SelectedTab {
84 pub fn toggle(&self) -> SelectedTab {
85 match self {
86 SelectedTab::ColorCodesToSpecs => SelectedTab::SpecsToColorCodes,
87 SelectedTab::SpecsToColorCodes => SelectedTab::ColorCodesToSpecs,
88 }
89 }
90}
91
92impl From<&SelectedTab> for Option<usize> {
93 fn from(selected_tab: &SelectedTab) -> Self {
94 match selected_tab {
95 SelectedTab::ColorCodesToSpecs => Some(0),
96 SelectedTab::SpecsToColorCodes => Some(1),
97 }
98 }
99}
100
101#[derive(Debug)]
102pub struct ColorCodesToSpecsModel {
103 pub selected_band: usize,
104 pub resistor: Resistor,
105}
106
107impl Default for ColorCodesToSpecsModel {
108 fn default() -> ColorCodesToSpecsModel {
109 ColorCodesToSpecsModel {
110 selected_band: 0,
111 resistor: Resistor::SixBand {
112 band1: rusistor::Color::Brown,
113 band2: rusistor::Color::Black,
114 band3: rusistor::Color::Black,
115 band4: rusistor::Color::Black,
116 band5: rusistor::Color::Brown,
117 band6: rusistor::Color::Black,
118 },
119 }
120 }
121}
122
123#[derive(Debug, Default, PartialEq)]
124pub struct InputState {
125 pub value: String,
126 pub cursor: usize,
127}
128
129#[derive(Debug, Default)]
130pub struct SpecsToColorModel {
131 pub resistance_input_state: InputState,
132 pub tolerance_input_state: InputState,
133 pub tcr_input_state: InputState,
134 pub focus: InputFocus,
135 pub resistor: Option<Resistor>,
136 pub history: SpecsHistory,
137 pub error: Option<String>,
138}
139
140impl SpecsToColorModel {
141 pub fn add_specs_to_history(&mut self) {
142 let specs = (
143 self.resistance_input_state.value.clone(),
144 self.tolerance_input_state.value.clone(),
145 self.tcr_input_state.value.clone(),
146 );
147 self.history.add(specs);
148 }
149
150 pub fn set_specs_from_history(&mut self) {
151 if let Some((a, b, c)) = self.history.try_get() {
152 self.resistance_input_state = InputState {
153 value: a.to_string(),
154 cursor: a.len(),
155 };
156 self.tolerance_input_state = InputState {
157 value: b.to_string(),
158 cursor: b.len(),
159 };
160 self.tcr_input_state = InputState {
161 value: c.to_string(),
162 cursor: c.len(),
163 };
164 }
165 }
166}