#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(clippy::unwrap_used)]
use tinyklv::prelude::*; use tinyklv::dec::binary as decb; use tinyklv::enc::binary as encb;
const LON_SCALE: f64 = 180.0 / (i32::MAX as f64);
const LAT_SCALE: f64 = 90.0 / (i32::MAX as f64);
fn scale_lon_enc(v: &f64) -> Vec<u8> {
let data = (*v / LON_SCALE) as i32;
encb::be_i32(data)
}
fn scale_lat_enc(v: &f64) -> Vec<u8> {
let data = (*v / LAT_SCALE) as i32;
encb::be_i32(data)
}
fn scale_lon_dec(input: &mut &[u8]) -> tinyklv::Result<f64> {
let data = decb::be_i32(input)?;
Ok(data as f64 * LON_SCALE)
}
fn scale_lat_dec(input: &mut &[u8]) -> tinyklv::Result<f64> {
let data = decb::be_i32(input)?;
Ok(data as f64 * LAT_SCALE)
}
#[derive(Klv, Debug, PartialEq)]
#[klv(
stream = &[u8],
sentinel = b"GPSFIX",
key(dec = decb::u8, enc = encb::u8),
len(dec = decb::u8_as_usize, enc = encb::u8_from_usize),
)]
struct GpsFix {
#[klv(
key = 0x01,
dec = scale_lat_dec,
enc = scale_lat_enc,
)]
latitude_deg: f64,
#[klv(
key = 0x02,
dec = scale_lon_dec,
enc = scale_lon_enc,
)]
longitude_deg: f64,
#[klv(
key = 0x03,
dec = decb::be_u16,
enc = *encb::be_u16,
)]
hdop_centiunits: u16,
}
fn main() {
let original = GpsFix {
latitude_deg: 48.856_6,
longitude_deg: 2.352_2,
hdop_centiunits: 95, };
let frame = original.encode_frame();
let decoded = GpsFix::decode_frame(
&mut frame.as_slice(),
).unwrap();
assert!((decoded.latitude_deg - original.latitude_deg ).abs() < 1e-6);
assert!((decoded.longitude_deg - original.longitude_deg).abs() < 1e-6);
assert_eq!(decoded.hdop_centiunits, original.hdop_centiunits);
}