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
use crate::coords::{Course, Latitude, Longitude, MagneticCourse, Speed};
use crate::datetime::{Date, DateTime, Time};
use crate::modes::{Mode, Status};
use crate::Source;
#[derive(Debug, PartialEq)]
pub struct RMC {
pub source: Source,
pub datetime: DateTime,
pub latitude: Latitude,
pub longitude: Longitude,
pub speed: Speed,
pub course: Option<Course>,
pub magnetic: Option<MagneticCourse>,
pub mode: Mode,
}
impl RMC {
pub(crate) fn parse<'a>(
source: Source,
fields: &mut core::str::Split<'a, char>,
) -> Result<Option<Self>, &'static str> {
let time = Time::parse_from_hhmmss(fields.next())?;
let status = if let Some(f_status) = fields.next() {
Status::from_str(f_status)?
} else {
return Err("Status field is mandatory for RMC sentence!");
};
let latitude = Latitude::parse(fields.next(), fields.next())?;
let longitude = Longitude::parse(fields.next(), fields.next())?;
let speed = Speed::parse(fields.next())?;
let course = Course::parse(fields.next())?;
let date = Date::parse_from_ddmmyy(fields.next())?;
let magnetic = MagneticCourse::parse_from_mvar_mdir(&course, fields.next(), fields.next())?;
let mode = Mode::from_some_str_or_status(fields.next(), &status)?;
let datetime = DateTime::from_date_and_time(date, time)?;
if let (Some(datetime), Some(latitude), Some(longitude), Some(speed)) =
(datetime, latitude, longitude, speed)
{
Ok(Some(RMC {
source,
datetime,
latitude,
longitude,
speed,
course,
magnetic: magnetic,
mode,
}))
} else {
Ok(None)
}
}
}