#![allow(unused)]
pub mod bitread;
pub mod prelude;
pub mod bitvec {
pub use bitvec::prelude::*;
pub use bitvec::view::BitView;
}
pub use bitread::*;
pub use bitread_macro::*;
use crate::prelude::bitvec::order;
#[macro_export]
macro_rules! read_bits {
($data:expr, $offset:expr, 0, $type:ty) => {{
0 as $type
}};
($data:expr, $offset:expr, 1usize, bool) => {
$data[$offset]
};
($data:expr, $offset:expr, $bits:expr, $type:ty) => {
$data[$offset..$offset + $bits].load::<$type>()
};
}
#[cfg(test)]
mod tests {
use super::prelude::*;
#[derive(BitRead, Debug, PartialEq)]
#[bitrw(endian = "little", bit_order = "lsb")]
pub struct PositionWithInactivityTimer {
#[bitrw(bits = 1)]
last_fix_failed: bool,
#[bitrw(
bits = 23,
map = "|x: i32| { x as f64 * (180.0 / ((1 << 23) as f64)) }"
)]
latitude_degrees: f64,
#[bitrw(
bits = 24,
map = "|x: i32| { x as f64 * (360.0 / ((1 << 24) as f64)) }"
)]
longitude_degrees: f64,
#[bitrw(bits = 1)]
in_trip: bool,
#[bitrw(bits = 7)]
timestamp: u8,
#[bitrw(bits = 1)]
battery_critical: bool,
#[bitrw(bits = 1)]
inactivity_indicator_alarm: bool,
#[bitrw(bits = 14, map = "|x: u16| { x as u32 * 2 }")]
inactivity_timer_minutes: u32,
#[bitrw(bits = 8, map = "|x: u8| { 3.5 + x as f64 * 0.032 }")]
battery_voltage_volts: f64,
#[bitrw(bits = 3, map = "|x: u8| { x as u32 * 45 }")]
heading_degrees: u32,
#[bitrw(bits = 5, map = "|x: u8| { x as u32 * 5 }")]
speed_kmh: u32,
}
#[test]
fn test_parse_position_with_inactivity_timer() {
let data = vec![
0xE8, 0x25, 0xF4, 0x9B, 0x9E, 0x87, 0x2B, 0x6A, 0x99, 0x2A, 0xAB, ];
let position_with_inactivity_timer =
PositionWithInactivityTimer::read_from(data.as_slice()).unwrap();
assert_eq!(
position_with_inactivity_timer,
PositionWithInactivityTimer {
last_fix_failed: false,
latitude_degrees: -8.33338737487793,
longitude_degrees: -169.28500413894653,
in_trip: true,
timestamp: 21,
battery_critical: false,
inactivity_indicator_alarm: true,
inactivity_timer_minutes: 19636,
battery_voltage_volts: 4.844,
heading_degrees: 135,
speed_kmh: 105,
}
);
}
#[derive(BitRead, Debug, PartialEq)]
#[bitrw(endian = "little", bit_order = "lsb")]
pub struct SkipDefaultTest {
#[bitrw(bits = 1)]
last_fix_failed: bool,
#[bitrw(
bits = 23,
map = "|x: i32| { x as f64 * (180.0 / ((1 << 23) as f64)) }"
)]
latitude_degrees: f64,
#[bitrw(skip)]
longitude_degrees: f64,
#[bitrw(skip, default = "latitude_degrees * 2.0")]
latitude_degrees_times_two: f64,
}
#[test]
fn test_skip_and_default() {
let data = vec![
0xE8, 0x25, 0xF4, 0x9B, 0x9E, 0x87, 0x2B, 0x6A, 0x99, 0x2A, 0xAB, ];
let position_with_inactivity_timer = SkipDefaultTest::read_from(data.as_slice()).unwrap();
assert_eq!(
position_with_inactivity_timer,
SkipDefaultTest {
last_fix_failed: false,
latitude_degrees: -8.33338737487793,
longitude_degrees: 0.0,
latitude_degrees_times_two: -16.66677474975586,
}
);
}
}