sevensegment_parser/
lib.rs

1
2use crate::utils::cmp_vec_unordered;
3use std::str::FromStr;
4use std::fmt::Debug;
5
6mod utils;
7
8#[derive(PartialEq, PartialOrd, Debug)]
9pub enum SSDPart {
10  UpperTop = 0,
11  UpperLeft = 1,
12  UpperRight = 2,
13  Middle = 3,
14  LowerLeft = 4,
15  LowerRight = 5,
16  LowerBottom = 6,
17  Dot = 7,
18}
19
20struct SSDChars {
21  pub zero: Vec<SSDPart>,
22  pub one: Vec<SSDPart>,
23  pub two: Vec<SSDPart>,
24  pub three: Vec<SSDPart>,
25  pub four: Vec<SSDPart>,
26  pub five: Vec<SSDPart>,
27  pub six: Vec<SSDPart>,
28  pub seven: Vec<SSDPart>,
29  pub eight: Vec<SSDPart>,
30  pub nine: Vec<SSDPart>,
31  pub dot: Vec<SSDPart>,
32  pub minus: Vec<SSDPart>,
33}
34
35impl SSDChars {
36  pub fn default() -> Self {
37    use SSDPart::*;
38
39    return Self {
40      zero: vec![ UpperTop, UpperLeft, UpperRight, LowerLeft, LowerRight, LowerBottom ],
41      one: vec![ UpperRight, LowerRight ],
42      two: vec![ UpperTop, UpperRight, Middle, LowerLeft, LowerBottom ],
43      three: vec![ UpperTop, UpperRight, Middle, LowerRight, LowerBottom  ],
44      four: vec![ UpperLeft, UpperRight, Middle, LowerRight ],
45      five: vec![ UpperTop, UpperLeft, Middle, LowerRight, LowerBottom ],
46      six: vec![ UpperTop, UpperLeft, Middle, LowerLeft, LowerRight, LowerBottom ],
47      seven: vec![ UpperTop, UpperRight, LowerRight ],
48      eight: vec![ UpperTop, UpperLeft, UpperRight, Middle, LowerLeft, LowerRight, LowerBottom ],
49      nine: vec![ UpperTop, UpperLeft, UpperRight, Middle, LowerRight, LowerBottom ],
50      dot: vec![ Dot ],
51      minus: vec![ Middle ],
52    }
53  }
54}
55
56#[derive(Copy, Clone)]
57pub struct SegmentValue {
58  pub number: Option<u8>,
59  pub character: Option<char>
60}
61
62impl SegmentValue {
63  pub fn from_number(number: u8) -> Self {
64    Self {
65      number: Some(number),
66      character: None
67    }
68  }
69
70  pub fn from_char(character: char) -> Self {
71    Self {
72      number: None,
73      character: Some(character)
74    }
75  }
76
77  pub fn empty() -> Self {
78    Self {
79      number: None,
80      character: None
81    }
82  }
83
84  pub fn is_number(self: Self) -> bool {
85      self.number.is_some()
86  }
87
88  pub fn is_char(self) -> bool {
89    self.character.is_some()
90  }
91}
92
93pub fn read_segments( segments: Vec<Vec<SSDPart>> ) -> std::io::Result<String> {
94  let mut string = String::new();
95
96  for segment in segments {
97    let val = get_segment_value(segment).unwrap_or( SegmentValue::empty() );
98
99    if val.is_char() {
100      string.push(val.character.unwrap())
101    }
102
103    if val.is_number() {
104      let num = val.number.unwrap();
105
106      if num < 10 {
107        string.push_str(num.to_string().as_str());
108      }
109    }
110  }
111
112  Ok(string)
113}
114
115pub struct UnknownNumber<T> {
116  pub number: T,
117  pub is_negative: bool
118}
119
120pub fn read_number<T>( segments: Vec<Vec<SSDPart>> ) -> std::io::Result<UnknownNumber<T>>
121  where T: FromStr, <T as FromStr>::Err : Debug {
122  let mut parsed_segments = read_segments(segments)?;
123  let is_negative = parsed_segments.starts_with('-');
124
125  if is_negative {
126    parsed_segments = parsed_segments[1..].to_string()
127  }
128  
129  Ok(
130    UnknownNumber {
131      number: parsed_segments.parse::<T>().unwrap(),
132      is_negative
133    }
134  )
135}
136
137pub fn get_segment_value( segment: Vec<SSDPart> ) -> Option<SegmentValue> {
138  let default_segments = SSDChars::default();
139
140  if cmp_vec_unordered(&segment, default_segments.zero) {
141    return Some(SegmentValue::from_number(0));
142  }
143
144  if cmp_vec_unordered(&segment, default_segments.one) {
145    return Some(SegmentValue::from_number(1));
146  }
147
148  if cmp_vec_unordered(&segment, default_segments.two) {
149    return Some(SegmentValue::from_number(2));
150  }
151
152  if cmp_vec_unordered(&segment, default_segments.three) {
153    return Some(SegmentValue::from_number(3));
154  }
155
156  if cmp_vec_unordered(&segment, default_segments.four) {
157    return Some(SegmentValue::from_number(4));
158  }
159
160  if cmp_vec_unordered(&segment, default_segments.five) {
161    return Some(SegmentValue::from_number(5));
162  }
163
164  if cmp_vec_unordered(&segment, default_segments.six) {
165    return Some(SegmentValue::from_number(6));
166  }
167
168  if cmp_vec_unordered(&segment, default_segments.seven) {
169    return Some(SegmentValue::from_number(7));
170  }
171
172  if cmp_vec_unordered(&segment, default_segments.eight) {
173    return Some(SegmentValue::from_number(8));
174  }
175
176  if cmp_vec_unordered(&segment, default_segments.nine) {
177    return Some(SegmentValue::from_number(9));
178  }
179  
180  if cmp_vec_unordered(&segment, default_segments.dot) {
181    return Some(SegmentValue::from_char('.'))
182  }
183  
184  if cmp_vec_unordered(&segment, default_segments.minus) {
185    return Some(SegmentValue::from_char('-'))
186  }
187
188  None
189}
190