//! Utility methods for encoding and decoding various durations and intervals used within Insim. //! These 2 methods allow the milliseconds to be scaled using the const SCALE generic. //! This is useful as a number of LFS packets use centiseconds (1/100th of a second, rather than //! 1/1000th). use std::time::Duration; use binrw::{BinRead, BinWrite, Error as BinError}; #[allow(missing_docs)] #[binrw::writer(writer, endian)] pub fn binrw_write_duration< T: TryFrom + for<'a> BinWrite = ()>, const SCALE: u128, >( input: &Duration, ) -> binrw::BinResult<()> { let pos = writer.stream_position()?; match T::try_from(input.as_millis() / SCALE) { Ok(v) => v.write_options(writer, endian, ()), Err(_) => Err(BinError::AssertFail { pos, message: "Could not convert to duration without loss".into(), }), } } #[allow(missing_docs)] #[binrw::parser(reader, endian)] pub fn binrw_parse_duration + for<'a> BinRead = ()>, const SCALE: u64>( ) -> binrw::BinResult { let pos = reader.stream_position()?; let res = T::read_options(reader, endian, ())?; match TryInto::::try_into(res) { Ok(v) => Ok(Duration::from_millis(v * SCALE)), Err(_) => Err(BinError::AssertFail { pos, message: "Could not convert to duration without loss".into(), }), } }