#[must_use]
pub fn calculate_checksum(sentence: &str) -> u8 {
let mut cs: u8 = 0;
for (i, byte) in sentence.bytes().enumerate() {
if i == 0 && byte == b'$' {
continue;
}
if byte == b'*' {
break;
}
cs ^= byte;
}
cs
}
#[cfg(test)]
mod tests {
use super::calculate_checksum;
#[test]
fn test_calculate_checksum() {
let sentence = "GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,";
assert_eq!(calculate_checksum(sentence), 0x47);
let sentence = "$GPGLL,5057.970,N,00146.110,E,142451,A";
assert_eq!(calculate_checksum(sentence), 0x27);
let sentence = "$GPVTG,089.0,T,,,15.2,N,,";
assert_eq!(calculate_checksum(sentence), 0x7F);
}
#[test]
fn calculate_checksum_ignores_dollar_and_asterisk_tails() {
let expected = 0x37;
let sentence = "$GPGGA,0189.00,34.052200,N,-118.243700,W,2,8,1.2,0.0,M,1.00,2,42";
assert_eq!(calculate_checksum(sentence), expected);
let sentence = "$GPGGA,0189.00,34.052200,N,-118.243700,W,2,8,1.2,0.0,M,1.00,2,42*";
assert_eq!(calculate_checksum(sentence), expected);
let sentence = "$GPGGA,0189.00,34.052200,N,-118.243700,W,2,8,1.2,0.0,M,1.00,2,42*00";
assert_eq!(calculate_checksum(sentence), expected);
let sentence = "GPGGA,0189.00,34.052200,N,-118.243700,W,2,8,1.2,0.0,M,1.00,2,42*";
assert_eq!(calculate_checksum(sentence), expected);
let sentence = "GPGGA,0189.00,34.052200,N,-118.243700,W,2,8,1.2,0.0,M,1.00,2,42*00";
assert_eq!(calculate_checksum(sentence), expected);
}
}