///|
pub(all) struct GllRecord {
talker_value : String
latitude_value : Coordinate
longitude_value : Coordinate
time_value : UtcTime
status_value : RmcStatus
mode_value : String?
} derive(Eq, Debug)
///|
fn gll_error(message : String) -> NmeaError {
NmeaError::from_diagnostic(
Diagnostic::new(SentenceInvalid, Error, message, SourceRef::sentence(0)),
)
}
///|
pub fn parse_gll(frame : NmeaFrame) -> Result[GllRecord, NmeaError] {
if frame.formatter() != "GLL" {
return Err(gll_error("frame formatter is not GLL"))
}
let cursor = FieldCursor::new(frame.fields())
let latitude_text = match cursor.required(0) {
Ok(value) => value
Err(error) => return Err(error)
}
let latitude_hemi = match cursor.required(1) {
Ok(value) => value
Err(error) => return Err(error)
}
let longitude_text = match cursor.required(2) {
Ok(value) => value
Err(error) => return Err(error)
}
let longitude_hemi = match cursor.required(3) {
Ok(value) => value
Err(error) => return Err(error)
}
let time_text = match cursor.required(4) {
Ok(value) => value
Err(error) => return Err(error)
}
let status_text = match cursor.required(5) {
Ok(value) => value
Err(error) => return Err(error)
}
let status = if status_text == "A" {
Active
} else if status_text == "V" {
Void
} else {
return Err(gll_error("GLL status must be A or V"))
}
let latitude = match
parse_latitude(latitude_text, latitude_hemi, SourceRef::field(0, 0)) {
Ok(value) => value
Err(error) => return Err(error)
}
let longitude = match
parse_longitude(longitude_text, longitude_hemi, SourceRef::field(0, 2)) {
Ok(value) => value
Err(error) => return Err(error)
}
let time = match UtcTime::parse(time_text, SourceRef::field(0, 4)) {
Ok(value) => value
Err(error) => return Err(error)
}
let mode = match cursor.optional(6) {
Ok(value) => value
Err(error) => return Err(error)
}
Ok({
talker_value: frame.talker(),
latitude_value: latitude,
longitude_value: longitude,
time_value: time,
status_value: status,
mode_value: mode,
})
}
///|
pub fn GllRecord::latitude(self : GllRecord) -> Coordinate {
self.latitude_value
}
///|
pub fn GllRecord::longitude(self : GllRecord) -> Coordinate {
self.longitude_value
}
///|
pub fn GllRecord::time(self : GllRecord) -> UtcTime {
self.time_value
}
///|
pub fn GllRecord::status(self : GllRecord) -> RmcStatus {
self.status_value
}
///|
pub fn GllRecord::mode(self : GllRecord) -> String? {
self.mode_value
}
///|
pub fn GllRecord::encode(self : GllRecord) -> Result[String, NmeaError] {
let fields = [
coordinate_wire_text(self.latitude_value),
if self.latitude_value.hemisphere_value == 78 {
"N"
} else {
"S"
},
coordinate_wire_text(self.longitude_value),
if self.longitude_value.hemisphere_value == 69 {
"E"
} else {
"W"
},
utc_time_wire(self.time_value),
match self.status_value {
Active => "A"
Void => "V"
},
]
match self.mode_value {
Some(mode) => fields.push(mode)
None => ()
}
Ok(NmeaFrame::new(36, self.talker_value, "GLL", fields).encode())
}