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 67 68 69
use core::str::from_utf8_unchecked; use crate::messages::gga::GGA; use crate::messages::gns::GNS; use crate::messages::gsa::GSA; use crate::messages::rmc::RMC; #[derive(Copy, Clone, Debug, PartialEq)] pub enum SentenceFormatter { GGA = 0, GNS, GSA, RMC, } impl SentenceFormatter { pub fn try_from(bytes: &[u8]) -> Option<SentenceFormatter> { match bytes { b"GGA" => Some(Self::GGA), b"GNS" => Some(Self::GNS), b"GSA" => Some(Self::GSA), b"RMC" => Some(Self::RMC), _ => None, } } } #[derive(Clone, Debug)] pub enum Message { GNS(GNS), GGA(GGA), GSA(GSA), RMC(RMC), } impl Message { pub fn try_from(line: &[u8]) -> Option<Message> { let mut splitted = line.rsplitn(2, |&b| b == b'*'); let checksum = match splitted.next() { Some(c) => u8::from_str_radix(unsafe { from_utf8_unchecked(c) }, 16).unwrap_or(0), None => return None, }; let payload = match splitted.next() { Some(v) => v, None => return None, }; if payload.iter().fold(0, |csum, &b| csum ^ b) != checksum { return None; } let mut splitted = payload.splitn(2, |&b| b == b','); let address = splitted.next().unwrap(); let value = match splitted.next() { Some(v) => v, None => return None, }; match &address[2..] { b"GGA" => Some(Message::GGA(GGA::from(value))), b"GNS" => Some(Message::GNS(GNS::from(value))), b"GSA" => Some(Message::GSA(GSA::from(value))), b"RMC" => Some(Message::RMC(RMC::from(value))), _ => None, } } }