rustedbytes_nmea/message/
gll.rs1use crate::message::ParsedSentence;
42use crate::types::{MessageType, TalkerId};
43
44#[derive(Debug, Clone)]
46pub struct GllData {
47 pub talker_id: TalkerId,
48 pub latitude: f64,
49 pub lat_direction: char,
50 pub longitude: f64,
51 pub lon_direction: char,
52 time_data: [u8; 16],
53 time_len: u8,
54 pub status: char,
55}
56
57impl GllData {
58 pub fn time(&self) -> &str {
60 core::str::from_utf8(&self.time_data[..self.time_len as usize]).unwrap_or("")
61 }
62}
63
64impl ParsedSentence {
65 pub fn as_gll(&self) -> Option<GllData> {
104 if self.message_type != MessageType::GLL {
105 return None;
106 }
107
108 let latitude: f64 = self.parse_field(1)?;
110 let lat_direction = self.parse_field_char(2)?;
111 let longitude: f64 = self.parse_field(3)?;
112 let lon_direction = self.parse_field_char(4)?;
113 let time_str = self.get_field_str(5)?;
114 let status = self.parse_field_char(6)?;
115
116 let mut time_data = [0u8; 16];
118 let time_bytes = time_str.as_bytes();
119 let time_len = time_bytes.len().min(16) as u8;
120 time_data[..time_len as usize].copy_from_slice(&time_bytes[..time_len as usize]);
121
122 Some(GllData {
123 talker_id: self.talker_id,
124 latitude,
125 lat_direction,
126 longitude,
127 lon_direction,
128 time_data,
129 time_len,
130 status,
131 })
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use crate::NmeaParser;
138
139 #[test]
140 fn test_gll_complete_message() {
141 let parser = NmeaParser::new();
142 let sentence = b"$GPGLL,4916.45,N,12311.12,W,225444,A*1D\r\n";
143
144 let result = parser.parse_sentence_complete(sentence);
145
146 assert!(result.is_some());
147 let msg = result.unwrap();
148 let gll = msg.as_gll();
149 assert!(gll.is_some());
150
151 let gll_data = gll.unwrap();
152 assert_eq!(gll_data.latitude, 4916.45);
153 assert_eq!(gll_data.lat_direction, 'N');
154 assert_eq!(gll_data.longitude, 12311.12);
155 assert_eq!(gll_data.lon_direction, 'W');
156 assert_eq!(gll_data.time(), "225444");
157 assert_eq!(gll_data.status, 'A');
158 }
159
160 #[test]
161 fn test_gll_void_status() {
162 let parser = NmeaParser::new();
163 let sentence = b"$GPGLL,4916.45,N,12311.12,W,225444,V*1D\r\n";
164
165 let result = parser.parse_sentence_complete(sentence);
166
167 assert!(result.is_some());
168 let msg = result.unwrap();
169 let gll = msg.as_gll();
170 assert!(gll.is_some());
171
172 let gll_data = gll.unwrap();
173 assert_eq!(gll_data.status, 'V');
174 }
175
176 #[test]
177 fn test_gll_south_east() {
178 let parser = NmeaParser::new();
179 let sentence = b"$GPGLL,3723.2475,S,14507.3647,E,225444,A*1D\r\n";
180
181 let result = parser.parse_sentence_complete(sentence);
182
183 assert!(result.is_some());
184 let msg = result.unwrap();
185 let gll = msg.as_gll();
186 assert!(gll.is_some());
187
188 let gll_data = gll.unwrap();
189 assert_eq!(gll_data.lat_direction, 'S');
190 assert_eq!(gll_data.lon_direction, 'E');
191 }
192
193 #[test]
194 fn test_gll_missing_latitude() {
195 let parser = NmeaParser::new();
196 let sentence = b"$GPGLL,,N,12311.12,W,225444,A*1D\r\n";
197
198 let result = parser.parse_sentence_complete(sentence);
199
200 assert!(result.is_none());
202 }
203
204 #[test]
205 fn test_gll_missing_longitude() {
206 let parser = NmeaParser::new();
207 let sentence = b"$GPGLL,4916.45,N,,W,225444,A*1D\r\n";
208
209 let result = parser.parse_sentence_complete(sentence);
210
211 assert!(result.is_none());
213 }
214
215 #[test]
216 fn test_gll_missing_time() {
217 let parser = NmeaParser::new();
218 let sentence = b"$GPGLL,4916.45,N,12311.12,W,,A*1D\r\n";
219
220 let result = parser.parse_sentence_complete(sentence);
221
222 assert!(result.is_none());
224 }
225
226 #[test]
227 fn test_gll_missing_status() {
228 let parser = NmeaParser::new();
229 let sentence = b"$GPGLL,4916.45,N,12311.12,W,225444,*1D\r\n";
230
231 let result = parser.parse_sentence_complete(sentence);
232
233 assert!(result.is_none());
235 }
236
237 #[test]
238 fn test_gll_invalid_latitude() {
239 let parser = NmeaParser::new();
240 let sentence = b"$GPGLL,INVALID,N,12311.12,W,225444,A*1D\r\n";
241
242 let result = parser.parse_sentence_complete(sentence);
243
244 assert!(result.is_none());
246 }
247
248 #[test]
249 fn test_gll_numeric_precision() {
250 let parser = NmeaParser::new();
251 let sentence = b"$GPGLL,4916.45,N,12311.12,W,225444,A*1D\r\n";
252
253 let result = parser.parse_sentence_complete(sentence);
254
255 assert!(result.is_some());
256 let msg = result.unwrap();
257 let gll = msg.as_gll();
258 assert!(gll.is_some());
259
260 let gll_data = gll.unwrap();
261 assert!((gll_data.latitude - 4916.45).abs() < 0.01);
262 assert!((gll_data.longitude - 12311.12).abs() < 0.01);
263 }
264
265 #[test]
266 fn test_gll_high_precision_coordinates() {
267 let parser = NmeaParser::new();
268 let sentence = b"$GPGLL,4916.453789,N,12311.125678,W,225444,A*1D\r\n";
269
270 let result = parser.parse_sentence_complete(sentence);
271
272 assert!(result.is_some());
273 let msg = result.unwrap();
274 let gll = msg.as_gll();
275 assert!(gll.is_some());
276
277 let gll_data = gll.unwrap();
278 assert!((gll_data.latitude - 4916.453789).abs() < 0.000001);
279 assert!((gll_data.longitude - 12311.125678).abs() < 0.000001);
280 }
281
282 #[test]
283 fn test_gll_different_talker_id() {
284 let parser = NmeaParser::new();
285 let sentence = b"$GNGLL,4916.45,N,12311.12,W,225444,A*1D\r\n";
287
288 let result = parser.parse_sentence_complete(sentence);
289
290 assert!(result.is_some());
291 let msg = result.unwrap();
292 let gll = msg.as_gll();
293 assert!(gll.is_some());
294
295 let gll_data = gll.unwrap();
296 assert_eq!(gll_data.talker_id, crate::types::TalkerId::GN);
297 }
298
299 #[test]
300 fn test_gll_all_constellation_types() {
301 let parser = NmeaParser::new();
302
303 let gp_sentence = b"$GPGLL,4916.45,N,12311.12,W,225444,A*1D\r\n";
305 let gp_result = parser.parse_sentence_complete(gp_sentence);
306 assert!(gp_result.is_some());
307 let gp_msg = gp_result.unwrap();
308 let gp_gll = gp_msg.as_gll().unwrap();
309 assert_eq!(gp_gll.talker_id, crate::types::TalkerId::GP);
310
311 let gb_sentence = b"$GBGLL,4916.45,N,12311.12,W,225444,A*1D\r\n";
313 let gb_result = parser.parse_sentence_complete(gb_sentence);
314 assert!(gb_result.is_some());
315 let gb_msg = gb_result.unwrap();
316 let gb_gll = gb_msg.as_gll().unwrap();
317 assert_eq!(gb_gll.talker_id, crate::types::TalkerId::GB);
318 }
319
320 #[test]
321 fn test_gll_time_with_decimals() {
322 let parser = NmeaParser::new();
323 let sentence = b"$GPGLL,4916.45,N,12311.12,W,225444.50,A*1D\r\n";
324
325 let result = parser.parse_sentence_complete(sentence);
326
327 assert!(result.is_some());
328 let msg = result.unwrap();
329 let gll = msg.as_gll();
330 assert!(gll.is_some());
331
332 let gll_data = gll.unwrap();
333 assert_eq!(gll_data.time(), "225444.50");
334 }
335}