1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::str::FromStr;
use APRSError;
#[derive(Eq, PartialEq, Debug, Clone)]
pub enum Timestamp {
DDHHMM(u8, u8, u8),
HHMMSS(u8, u8, u8),
Unsupported(String),
}
impl FromStr for Timestamp {
type Err = APRSError;
fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
let b = s.as_bytes();
if b.len() != 7 {
return Err(APRSError::InvalidTimestamp(s.to_owned()));
}
let one = s[0..2].parse::<u8>().map_err(|_| APRSError::InvalidTimestamp(s.to_owned()))?;
let two = s[2..4].parse::<u8>().map_err(|_| APRSError::InvalidTimestamp(s.to_owned()))?;
let three = s[4..6].parse::<u8>().map_err(|_| APRSError::InvalidTimestamp(s.to_owned()))?;
Ok(match b[6] as char {
'z' => Timestamp::DDHHMM(one, two, three),
'h' => Timestamp::HHMMSS(one, two, three),
'/' => Timestamp::Unsupported(s.to_owned()),
_ => return Err(APRSError::InvalidTimestamp(s.to_owned())),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_ddhhmm() {
assert_eq!("123456z".parse(), Ok(Timestamp::DDHHMM(12, 34, 56)));
}
#[test]
fn parse_hhmmss() {
assert_eq!("123456h".parse(), Ok(Timestamp::HHMMSS(12, 34, 56)));
}
#[test]
fn parse_local_time() {
assert_eq!("123456/".parse::<Timestamp>(), Ok(Timestamp::Unsupported("123456/".to_owned())));
}
#[test]
fn invalid_timestamp() {
assert_eq!("1234567".parse::<Timestamp>(), Err(APRSError::InvalidTimestamp("1234567".to_owned())));
}
#[test]
fn invalid_timestamp2() {
assert_eq!("123a56z".parse::<Timestamp>(), Err(APRSError::InvalidTimestamp("123a56z".to_owned())));
}
}