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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
use core::fmt::Debug; use core::str::from_utf8_unchecked as utf8; pub mod date; pub mod latitude; pub mod longitude; pub mod position_mode; pub mod time; pub type Quality = position_mode::PositionMode; #[derive(Copy, Clone, Debug, PartialEq)] pub enum OperationMode { Auto, Manual, } impl Default for OperationMode { fn default() -> Self { Self::Manual } } impl From<&[u8]> for OperationMode { fn from(bytes: &[u8]) -> Self { match bytes.first().map(|&b| b).unwrap_or(b'M') { b'A' => Self::Auto, b'M' => Self::Manual, _ => Self::Manual, } } } #[derive(Copy, Clone, Debug, PartialEq)] pub enum NavigationMode { NoFix, _3DFix, _2DFix, } impl Default for NavigationMode { fn default() -> Self { Self::NoFix } } impl From<&[u8]> for NavigationMode { fn from(bytes: &[u8]) -> Self { match bytes.first().map(|&b| b).unwrap_or(b'1') { b'1' => Self::NoFix, b'2' => Self::_2DFix, b'3' => Self::_3DFix, _ => Self::NoFix, } } } #[derive(Copy, Clone, Default, Debug, PartialEq)] pub struct Status(pub bool); impl From<&[u8]> for Status { fn from(bytes: &[u8]) -> Self { Self(bytes.first().map(|&b| b).unwrap_or(b'V') == b'A') } } #[derive(Copy, Clone, Default, PartialEq)] pub struct IntegerDecimal(isize); impl IntegerDecimal { pub fn new(value: isize, decimal_length: u8) -> Self { Self(value << 8 | decimal_length as isize) } pub fn decimal_length(self) -> u8 { self.0 as u8 } pub fn exp(self) -> usize { let decimal_length = self.0 as u8; 10_usize.pow(decimal_length as u32) } pub fn integer(self) -> isize { let number = self.0 >> 8; number / self.exp() as isize } pub fn decimal(self) -> usize { let number = self.0 >> 8; let number = if number < 0 { -number } else { number } as usize; number % self.exp() } } impl core::ops::AddAssign<isize> for IntegerDecimal { fn add_assign(&mut self, value: isize) { self.0 += value * self.exp() as isize } } impl Into<f32> for IntegerDecimal { fn into(self) -> f32 { let number = self.0 >> 8; number as f32 / self.exp() as f32 } } impl Debug for IntegerDecimal { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "{}.{}#{}", self.integer(), self.decimal(), self.decimal_length()) } } impl From<&[u8]> for IntegerDecimal { fn from(bytes: &[u8]) -> Self { if bytes.len() == 0 { return Self::default(); } let mut splitted = bytes.split(|&b| b == b'.'); let mut integer = 0; if let Some(field) = splitted.next() { integer = unsafe { utf8(field) }.parse().unwrap_or_default(); } let mut decimal_length = 0; let mut decimal = 0; if let Some(field) = splitted.next() { decimal_length = core::cmp::min(field.len(), 255); decimal = unsafe { utf8(&field[..decimal_length]) }.parse().unwrap_or_default(); if integer < 0 { decimal = -decimal } } let exp = 10_isize.pow(decimal_length as u32); Self::new(integer * exp + decimal, decimal_length as u8) } }