1use core::str::FromStr;
2
3#[derive(Debug, Clone, Copy)]
5pub struct StartTime(pub f64);
6
7impl TryFrom<&str> for StartTime {
8 type Error = <f64 as FromStr>::Err;
9
10 fn try_from(value: &str) -> Result<Self, Self::Error> {
11 Ok(Self(value.parse()?))
12 }
13}
14
15#[derive(Debug, Clone, Copy)]
17pub enum RowType {
18 Address,
20 Start,
22 Stop,
24 Data,
26}
27
28impl TryFrom<&str> for RowType {
29 type Error = Error;
30
31 fn try_from(value: &str) -> Result<Self, Self::Error> {
32 match value.trim().replace("\"", "").to_ascii_lowercase().as_str() {
33 "address" => Ok(Self::Address),
34 "start" => Ok(Self::Start),
35 "stop" => Ok(Self::Stop),
36 "data" => Ok(Self::Data),
37 _ => Err(Error::InvalidRow),
38 }
39 }
40}
41
42#[derive(Debug, Clone)]
44pub struct ChannelName(String);
45
46impl<T: AsRef<str>> From<T> for ChannelName {
47 fn from(value: T) -> Self {
48 Self(value.as_ref().trim().replace("\"", ""))
49 }
50}
51
52#[derive(Debug, Clone, Copy)]
54pub enum Error {
55 Parse,
57 InvalidRow,
59}
60
61pub(crate) fn parse_hex(input: &str) -> Option<u8> {
63 let chars = input
64 .chars()
65 .map(|c| c.to_ascii_lowercase())
66 .collect::<Vec<char>>();
67 match *chars.as_slice() {
68 ['0', 'x', u, l] => Some(((hex_nibble_to_byte(u)?) << 4) | (hex_nibble_to_byte(l)?)),
69 _ => None,
70 }
71}
72
73pub(crate) fn hex_nibble_to_byte(c: char) -> Option<u8> {
75 match c {
76 '0'..='9' => Some((c as u8) - 48),
77 'a'..='f' => Some((c as u8) - 55 - 32),
78 _ => None,
79 }
80}