From 0115461bb5e6c8e876de1e3b50726218532ba00a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 3 Apr 2024 21:30:23 +0200 Subject: [PATCH 1/2] added additional ctors which only set the APID --- CHANGELOG.md | 4 ++++ src/lib.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0c0eae..b52a3d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). to `new_for_tc_checked`, `new_for_tm_checked`, `new_for_unseg_tc_checked` and `new_for_unseg_tm_checked`. +## Added + +- `SpHeader::new_from_apid` and `SpHeader::new_from_apid_checked` constructor. + # [v0.11.0-rc.1] 2024-04-03 Major API changes for the time API. If you are using the time API, it is strongly recommended diff --git a/src/lib.rs b/src/lib.rs index 18acc46..2de734a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -512,6 +512,35 @@ impl SpHeader { } } + /// This constructor sets the sequence flag field to [SequenceFlags::Unsegmented]. The data + /// length field is set to 1, which denotes an empty space packets. + /// + /// This constructor will panic if the APID exceeds [MAX_APID]. + pub const fn new_from_apid(apid: u16) -> Self { + SpHeader { + version: 0, + packet_id: PacketId::new(PacketType::Tm, false, apid), + psc: PacketSequenceCtrl { + seq_flags: SequenceFlags::Unsegmented, + seq_count: 0, + }, + data_len: 1, + } + } + + /// Checked variant of [Self::new_from_apid]. + pub fn new_from_apid_checked(apid: u16) -> Option { + Some(SpHeader { + version: 0, + packet_id: PacketId::new_checked(PacketType::Tm, false, apid)?, + psc: PacketSequenceCtrl { + seq_flags: SequenceFlags::Unsegmented, + seq_count: 0, + }, + data_len: 1, + }) + } + /// This constructor panics if the passed APID exceeds [MAX_APID] or the passed packet sequence /// count exceeds [MAX_SEQ_COUNT]. /// @@ -1180,4 +1209,16 @@ pub(crate) mod tests { let mut id_set = HashSet::new(); id_set.insert(PacketId::from(1_u16)); } + + #[test] + fn sp_header_from_apid() { + let sp_header = SpHeader::new_from_apid(0x03); + assert_eq!(sp_header.apid(), 0x03); + } + + #[test] + fn sp_header_from_apid_checked() { + let sp_header = SpHeader::new_from_apid_checked(0x03).unwrap(); + assert_eq!(sp_header.apid(), 0x03); + } } -- 2.43.0 From bbd66a6a8b54feea71f758e1403a273582a84e5f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Wed, 3 Apr 2024 21:56:26 +0200 Subject: [PATCH 2/2] added a lot of inline attrs --- CHANGELOG.md | 1 + src/cfdp/lv.rs | 12 +++++++++ src/cfdp/pdu/mod.rs | 31 +++++++++++++++++++++++ src/ecss/mod.rs | 7 ++++++ src/ecss/scheduling.rs | 1 + src/ecss/tc.rs | 45 +++++++++++++++++++++++++++++++++ src/ecss/tm.rs | 57 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 45 +++++++++++++++++++++++++++++++++ src/time/cds.rs | 15 ++++++++++- src/time/cuc.rs | 34 +++++++++++++++++++++++++ src/time/mod.rs | 4 +++ src/util.rs | 29 +++++++++++++++++++++ 12 files changed, 280 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b52a3d9..01f78e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Added - `SpHeader::new_from_apid` and `SpHeader::new_from_apid_checked` constructor. +- `#[inline]` attribute for a lot of small functions. # [v0.11.0-rc.1] 2024-04-03 diff --git a/src/cfdp/lv.rs b/src/cfdp/lv.rs index 7a8877b..638200a 100644 --- a/src/cfdp/lv.rs +++ b/src/cfdp/lv.rs @@ -62,6 +62,7 @@ pub(crate) fn generic_len_check_deserialization( } impl<'data> Lv<'data> { + #[inline] pub fn new(data: &[u8]) -> Result { if data.len() > u8::MAX as usize { return Err(TlvLvError::DataTooLarge(data.len())); @@ -73,6 +74,7 @@ impl<'data> Lv<'data> { } /// Creates a LV with an empty value field. + #[inline] pub fn new_empty() -> Lv<'data> { Lv { data: &[], @@ -82,6 +84,7 @@ impl<'data> Lv<'data> { /// Helper function to build a string LV. This is especially useful for the file or directory /// path LVs + #[inline] pub fn new_from_str(str_slice: &str) -> Result { Self::new(str_slice.as_bytes()) } @@ -89,37 +92,44 @@ impl<'data> Lv<'data> { /// Helper function to build a string LV. This is especially useful for the file or directory /// path LVs #[cfg(feature = "std")] + #[inline] pub fn new_from_string(string: &'data String) -> Result, TlvLvError> { Self::new(string.as_bytes()) } /// Returns the length of the value part, not including the length byte. + #[inline] pub fn len_value(&self) -> usize { self.data.len() } /// Returns the full raw length, including the length byte. + #[inline] pub fn len_full(&self) -> usize { self.len_value() + 1 } /// Checks whether the value field is empty. + #[inline] pub fn is_empty(&self) -> bool { self.data.len() == 0 } + #[inline] pub fn value(&self) -> &[u8] { self.data } /// If the LV was generated from a raw bytestream using [Self::from_bytes], the raw start /// of the LV can be retrieved with this method. + #[inline] pub fn raw_data(&self) -> Option<&[u8]> { self.raw_data } /// Convenience function to extract the value as a [str]. This is useful if the LV is /// known to contain a [str], for example being a file name. + #[inline] pub fn value_as_str(&self) -> Option> { if self.is_empty() { return None; @@ -135,6 +145,7 @@ impl<'data> Lv<'data> { } /// Reads a LV from a raw buffer. + #[inline] pub fn from_bytes(buf: &'data [u8]) -> Result, ByteConversionError> { generic_len_check_deserialization(buf, MIN_LV_LEN)?; Self::from_be_bytes_no_len_check(buf) @@ -151,6 +162,7 @@ impl<'data> Lv<'data> { MIN_LV_LEN + self.data.len() } + #[inline] pub(crate) fn from_be_bytes_no_len_check( buf: &'data [u8], ) -> Result, ByteConversionError> { diff --git a/src/cfdp/pdu/mod.rs b/src/cfdp/pdu/mod.rs index 1ff73a8..b1c6b14 100644 --- a/src/cfdp/pdu/mod.rs +++ b/src/cfdp/pdu/mod.rs @@ -150,12 +150,14 @@ impl Error for PduError { } impl From for PduError { + #[inline] fn from(value: ByteConversionError) -> Self { Self::ByteConversion(value) } } impl From for PduError { + #[inline] fn from(e: TlvLvError) -> Self { Self::TlvLvError(e) } @@ -179,33 +181,42 @@ pub trait WritablePduPacket { pub trait CfdpPdu { fn pdu_header(&self) -> &PduHeader; + #[inline] fn source_id(&self) -> UnsignedByteField { self.pdu_header().common_pdu_conf().source_entity_id } + #[inline] fn dest_id(&self) -> UnsignedByteField { self.pdu_header().common_pdu_conf().dest_entity_id } + #[inline] fn transaction_seq_num(&self) -> UnsignedByteField { self.pdu_header().common_pdu_conf().transaction_seq_num } + #[inline] fn transmission_mode(&self) -> TransmissionMode { self.pdu_header().common_pdu_conf().trans_mode } + + #[inline] fn direction(&self) -> Direction { self.pdu_header().common_pdu_conf().direction } + #[inline] fn crc_flag(&self) -> CrcFlag { self.pdu_header().common_pdu_conf().crc_flag } + #[inline] fn file_flag(&self) -> LargeFileFlag { self.pdu_header().common_pdu_conf().file_flag } + #[inline] fn pdu_type(&self) -> PduType { self.pdu_header().pdu_type() } @@ -234,6 +245,7 @@ pub struct CommonPduConfig { // TODO: Builder pattern might be applicable here.. impl CommonPduConfig { + #[inline] pub fn new( source_id: impl Into, dest_id: impl Into, @@ -265,6 +277,7 @@ impl CommonPduConfig { }) } + #[inline] pub fn new_with_byte_fields( source_id: impl Into, dest_id: impl Into, @@ -281,10 +294,12 @@ impl CommonPduConfig { ) } + #[inline] pub fn source_id(&self) -> UnsignedByteField { self.source_entity_id } + #[inline] fn source_dest_id_check( source_id: impl Into, dest_id: impl Into, @@ -307,6 +322,7 @@ impl CommonPduConfig { Ok((source_id, dest_id)) } + #[inline] pub fn set_source_and_dest_id( &mut self, source_id: impl Into, @@ -318,6 +334,7 @@ impl CommonPduConfig { Ok(()) } + #[inline] pub fn dest_id(&self) -> UnsignedByteField { self.dest_entity_id } @@ -326,6 +343,7 @@ impl CommonPduConfig { impl Default for CommonPduConfig { /// The defaults for the source ID, destination ID and the transaction sequence number is the /// [UnsignedByteFieldU8] with an intitial value of 0 + #[inline] fn default() -> Self { // The new function can not fail for these input parameters. Self::new( @@ -342,6 +360,7 @@ impl Default for CommonPduConfig { } impl PartialEq for CommonPduConfig { + #[inline] fn eq(&self, other: &Self) -> bool { self.source_entity_id.value() == other.source_entity_id.value() && self.dest_entity_id.value() == other.dest_entity_id.value() @@ -370,6 +389,7 @@ pub struct PduHeader { } impl PduHeader { + #[inline] pub fn new_for_file_data( pdu_conf: CommonPduConfig, pdu_datafield_len: u16, @@ -385,6 +405,7 @@ impl PduHeader { ) } + #[inline] pub fn new_for_file_data_default(pdu_conf: CommonPduConfig, pdu_datafield_len: u16) -> Self { Self::new_generic( PduType::FileData, @@ -394,6 +415,7 @@ impl PduHeader { SegmentationControl::NoRecordBoundaryPreservation, ) } + #[inline] pub fn new_no_file_data(pdu_conf: CommonPduConfig, pdu_datafield_len: u16) -> Self { Self::new_generic( PduType::FileDirective, @@ -404,6 +426,7 @@ impl PduHeader { ) } + #[inline] pub fn new_generic( pdu_type: PduType, pdu_conf: CommonPduConfig, @@ -421,6 +444,7 @@ impl PduHeader { } /// Returns only the length of the PDU header when written to a raw buffer. + #[inline] pub fn header_len(&self) -> usize { FIXED_HEADER_LEN + self.pdu_conf.source_entity_id.size() @@ -428,12 +452,14 @@ impl PduHeader { + self.pdu_conf.dest_entity_id.size() } + #[inline] pub fn pdu_datafield_len(&self) -> usize { self.pdu_datafield_len.into() } /// Returns the full length of the PDU when written to a raw buffer, which is the header length /// plus the PDU datafield length. + #[inline] pub fn pdu_len(&self) -> usize { self.header_len() + self.pdu_datafield_len as usize } @@ -606,10 +632,13 @@ impl PduHeader { current_idx, )) } + + #[inline] pub fn pdu_type(&self) -> PduType { self.pdu_type } + #[inline] pub fn common_pdu_conf(&self) -> &CommonPduConfig { &self.pdu_conf } @@ -617,6 +646,8 @@ impl PduHeader { pub fn seg_metadata_flag(&self) -> SegmentMetadataFlag { self.seg_metadata_flag } + + #[inline] pub fn seg_ctrl(&self) -> SegmentationControl { self.seg_ctrl } diff --git a/src/ecss/mod.rs b/src/ecss/mod.rs index e9febff..ad84a81 100644 --- a/src/ecss/mod.rs +++ b/src/ecss/mod.rs @@ -262,9 +262,13 @@ pub(crate) fn verify_crc16_ccitt_false_from_raw(raw_data: &[u8]) -> bool { macro_rules! ccsds_impl { () => { delegate!(to self.sp_header { + #[inline] fn ccsds_version(&self) -> u8; + #[inline] fn packet_id(&self) -> crate::PacketId; + #[inline] fn psc(&self) -> crate::PacketSequenceCtrl; + #[inline] fn data_len(&self) -> u16; }); } @@ -273,8 +277,11 @@ macro_rules! ccsds_impl { macro_rules! sp_header_impls { () => { delegate!(to self.sp_header { + #[inline] pub fn set_apid(&mut self, apid: u16) -> bool; + #[inline] pub fn set_seq_count(&mut self, seq_count: u16) -> bool; + #[inline] pub fn set_seq_flags(&mut self, seq_flag: SequenceFlags); }); } diff --git a/src/ecss/scheduling.rs b/src/ecss/scheduling.rs index d9b50b1..5d7b401 100644 --- a/src/ecss/scheduling.rs +++ b/src/ecss/scheduling.rs @@ -54,6 +54,7 @@ pub enum SchedStatus { } impl From for SchedStatus { + #[inline] fn from(value: bool) -> Self { if value { SchedStatus::Enabled diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 348ecfe..97bf7e7 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -111,22 +111,27 @@ pub mod zc { } impl GenericPusTcSecondaryHeader for PusTcSecondaryHeader { + #[inline] fn pus_version(&self) -> PusVersion { PusVersion::try_from(self.version_ack >> 4 & 0b1111).unwrap_or(PusVersion::Invalid) } + #[inline] fn ack_flags(&self) -> u8 { self.version_ack & 0b1111 } + #[inline] fn service(&self) -> u8 { self.service } + #[inline] fn subservice(&self) -> u8 { self.subservice } + #[inline] fn source_id(&self) -> u16 { self.source_id.get() } @@ -155,22 +160,27 @@ pub struct PusTcSecondaryHeader { } impl GenericPusTcSecondaryHeader for PusTcSecondaryHeader { + #[inline] fn pus_version(&self) -> PusVersion { self.version } + #[inline] fn ack_flags(&self) -> u8 { self.ack } + #[inline] fn service(&self) -> u8 { self.service } + #[inline] fn subservice(&self) -> u8 { self.subservice } + #[inline] fn source_id(&self) -> u16 { self.source_id } @@ -191,6 +201,7 @@ impl TryFrom for PusTcSecondaryHeader { } impl PusTcSecondaryHeader { + #[inline] pub fn new_simple(service: u8, subservice: u8) -> Self { PusTcSecondaryHeader { service, @@ -201,6 +212,7 @@ impl PusTcSecondaryHeader { } } + #[inline] pub fn new(service: u8, subservice: u8, ack: u8, source_id: u16) -> Self { PusTcSecondaryHeader { service, @@ -242,6 +254,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { /// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length /// field. If this is not set to true, [Self::update_ccsds_data_len] can be called to set /// the correct value to this field manually + #[inline] pub fn new( sp_header: &mut SpHeader, sec_header: PusTcSecondaryHeader, @@ -263,6 +276,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { /// Simplified version of the [Self::new] function which allows to only specify service /// and subservice instead of the full PUS TC secondary header. + #[inline] pub fn new_simple( sph: &mut SpHeader, service: u8, @@ -278,6 +292,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { ) } + #[inline] pub fn new_no_app_data( sp_header: &mut SpHeader, sec_header: PusTcSecondaryHeader, @@ -286,10 +301,12 @@ impl<'raw_data> PusTcCreator<'raw_data> { Self::new(sp_header, sec_header, &[], set_ccsds_len) } + #[inline] pub fn sp_header(&self) -> &SpHeader { &self.sp_header } + #[inline] pub fn set_ack_field(&mut self, ack: u8) -> bool { if ack > 0b1111 { return false; @@ -298,6 +315,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { true } + #[inline] pub fn set_source_id(&mut self, source_id: u16) { self.sec_header.source_id = source_id; } @@ -310,6 +328,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { /// If this was not done or the application data is set or changed after construction, /// this function needs to be called to ensure that the data length field of the CCSDS header /// is set correctly. + #[inline] pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = self.len_written() as u16 - size_of::() as u16 - 1; @@ -345,6 +364,7 @@ impl<'raw_data> PusTcCreator<'raw_data> { } impl WritablePusPacket for PusTcCreator<'_> { + #[inline] fn len_written(&self) -> usize { PUS_TC_MIN_LEN_WITHOUT_APP_DATA + self.app_data.len() } @@ -385,15 +405,20 @@ impl CcsdsPacket for PusTcCreator<'_> { impl PusPacket for PusTcCreator<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; }); + #[inline] fn user_data(&self) -> &[u8] { self.app_data } + #[inline] fn crc16(&self) -> Option { Some(self.calc_own_crc16()) } @@ -401,10 +426,15 @@ impl PusPacket for PusTcCreator<'_> { impl GenericPusTcSecondaryHeader for PusTcCreator<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; + #[inline] fn source_id(&self) -> u16; + #[inline] fn ack_flags(&self) -> u8; }); } @@ -482,24 +512,29 @@ impl<'raw_data> PusTcReader<'raw_data> { Ok((pus_tc, total_len)) } + #[inline] pub fn app_data(&self) -> &[u8] { self.user_data() } + #[inline] pub fn raw_data(&self) -> &[u8] { self.raw_data } + #[inline] pub fn len_packed(&self) -> usize { self.sp_header.total_len() } + #[inline] pub fn sp_header(&self) -> &SpHeader { &self.sp_header } } impl PartialEq for PusTcReader<'_> { + #[inline] fn eq(&self, other: &Self) -> bool { self.raw_data == other.raw_data } @@ -511,15 +546,20 @@ impl CcsdsPacket for PusTcReader<'_> { impl PusPacket for PusTcReader<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; }); + #[inline] fn user_data(&self) -> &[u8] { self.app_data } + #[inline] fn crc16(&self) -> Option { Some(self.crc16) } @@ -527,10 +567,15 @@ impl PusPacket for PusTcReader<'_> { impl GenericPusTcSecondaryHeader for PusTcReader<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; + #[inline] fn source_id(&self) -> u16; + #[inline] fn ack_flags(&self) -> u8; }); } diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index a41ecce..56d1e8e 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -86,27 +86,33 @@ pub mod zc { } impl GenericPusTmSecondaryHeader for PusTmSecHeaderWithoutTimestamp { + #[inline] fn pus_version(&self) -> PusVersion { PusVersion::try_from(self.pus_version_and_sc_time_ref_status >> 4 & 0b1111) .unwrap_or(PusVersion::Invalid) } + #[inline] fn sc_time_ref_status(&self) -> u8 { self.pus_version_and_sc_time_ref_status & 0b1111 } + #[inline] fn service(&self) -> u8 { self.service } + #[inline] fn subservice(&self) -> u8 { self.subservice } + #[inline] fn msg_counter(&self) -> u16 { self.msg_counter.get() } + #[inline] fn dest_id(&self) -> u16 { self.dest_id.get() } @@ -127,15 +133,18 @@ pub struct PusTmSecondaryHeader<'stamp> { } impl<'stamp> PusTmSecondaryHeader<'stamp> { + #[inline] pub fn new_simple(service: u8, subservice: u8, time_stamp: &'stamp [u8]) -> Self { Self::new(service, subservice, 0, 0, time_stamp) } /// Like [Self::new_simple] but without a timestamp. + #[inline] pub fn new_simple_no_timestamp(service: u8, subservice: u8) -> Self { Self::new(service, subservice, 0, 0, &[]) } + #[inline] pub fn new( service: u8, subservice: u8, @@ -156,26 +165,32 @@ impl<'stamp> PusTmSecondaryHeader<'stamp> { } impl GenericPusTmSecondaryHeader for PusTmSecondaryHeader<'_> { + #[inline] fn pus_version(&self) -> PusVersion { self.pus_version } + #[inline] fn sc_time_ref_status(&self) -> u8 { self.sc_time_ref_status } + #[inline] fn service(&self) -> u8 { self.service } + #[inline] fn subservice(&self) -> u8 { self.subservice } + #[inline] fn msg_counter(&self) -> u16 { self.msg_counter } + #[inline] fn dest_id(&self) -> u16 { self.dest_id } @@ -184,6 +199,7 @@ impl GenericPusTmSecondaryHeader for PusTmSecondaryHeader<'_> { impl<'slice> TryFrom> for PusTmSecondaryHeader<'slice> { type Error = (); + #[inline] fn try_from(sec_header: zc::PusTmSecHeader<'slice>) -> Result { Ok(PusTmSecondaryHeader { pus_version: sec_header.zc_header.pus_version(), @@ -235,6 +251,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { /// * `set_ccsds_len` - Can be used to automatically update the CCSDS space packet data length /// field. If this is not set to true, [Self::update_ccsds_data_len] can be called to set /// the correct value to this field manually + #[inline] pub fn new( sp_header: &mut SpHeader, sec_header: PusTmSecondaryHeader<'time>, @@ -255,6 +272,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { pus_tm } + #[inline] pub fn new_simple( sp_header: &mut SpHeader, service: u8, @@ -275,6 +293,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { )) } + #[inline] pub fn new_no_source_data( sp_header: &mut SpHeader, sec_header: PusTmSecondaryHeader<'time>, @@ -283,22 +302,27 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { Self::new(sp_header, sec_header, &[], set_ccsds_len) } + #[inline] pub fn timestamp(&self) -> &[u8] { self.sec_header.time_stamp } + #[inline] pub fn source_data(&self) -> &[u8] { self.source_data } + #[inline] pub fn set_dest_id(&mut self, dest_id: u16) { self.sec_header.dest_id = dest_id; } + #[inline] pub fn set_msg_counter(&mut self, msg_counter: u16) { self.sec_header.msg_counter = msg_counter } + #[inline] pub fn set_sc_time_ref_status(&mut self, sc_time_ref_status: u8) { self.sec_header.sc_time_ref_status = sc_time_ref_status & 0b1111; } @@ -310,6 +334,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { /// If this was not done or the time stamp or source data is set or changed after construction, /// this function needs to be called to ensure that the data length field of the CCSDS header /// is set correctly + #[inline] pub fn update_ccsds_data_len(&mut self) { self.sp_header.data_len = self.len_written() as u16 - size_of::() as u16 - 1; @@ -329,6 +354,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { } /// This helper function calls both [Self::update_ccsds_data_len] and [Self::calc_own_crc16] + #[inline] pub fn update_packet_fields(&mut self) { self.update_ccsds_data_len(); } @@ -386,6 +412,7 @@ impl<'time, 'raw_data> PusTmCreator<'time, 'raw_data> { } impl WritablePusPacket for PusTmCreator<'_, '_> { + #[inline] fn len_written(&self) -> usize { PUS_TM_MIN_LEN_WITHOUT_SOURCE_DATA + self.sec_header.time_stamp.len() @@ -411,15 +438,20 @@ impl CcsdsPacket for PusTmCreator<'_, '_> { impl PusPacket for PusTmCreator<'_, '_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; }); + #[inline] fn user_data(&self) -> &[u8] { self.source_data } + #[inline] fn crc16(&self) -> Option { Some(self.calc_own_crc16()) } @@ -427,11 +459,17 @@ impl PusPacket for PusTmCreator<'_, '_> { impl GenericPusTmSecondaryHeader for PusTmCreator<'_, '_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; + #[inline] fn dest_id(&self) -> u16; + #[inline] fn msg_counter(&self) -> u16; + #[inline] fn sc_time_ref_status(&self) -> u8; }); } @@ -518,19 +556,23 @@ impl<'raw_data> PusTmReader<'raw_data> { Ok((pus_tm, total_len)) } + #[inline] pub fn len_packed(&self) -> usize { self.sp_header.total_len() } + #[inline] pub fn source_data(&self) -> &[u8] { self.user_data() } + #[inline] pub fn timestamp(&self) -> &[u8] { self.sec_header.time_stamp } /// This function will return the slice [Self] was constructed from. + #[inline] pub fn raw_data(&self) -> &[u8] { self.raw_data } @@ -551,15 +593,20 @@ impl CcsdsPacket for PusTmReader<'_> { impl PusPacket for PusTmReader<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; }); + #[inline] fn user_data(&self) -> &[u8] { self.source_data } + #[inline] fn crc16(&self) -> Option { Some(self.crc16) } @@ -567,11 +614,17 @@ impl PusPacket for PusTmReader<'_> { impl GenericPusTmSecondaryHeader for PusTmReader<'_> { delegate!(to self.sec_header { + #[inline] fn pus_version(&self) -> PusVersion; + #[inline] fn service(&self) -> u8; + #[inline] fn subservice(&self) -> u8; + #[inline] fn dest_id(&self) -> u16; + #[inline] fn msg_counter(&self) -> u16; + #[inline] fn sc_time_ref_status(&self) -> u8; }); } @@ -633,6 +686,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { /// Set the sequence count. Returns false and does not update the value if the passed value /// exceeds [MAX_APID]. + #[inline] pub fn set_apid(&mut self, apid: u16) -> bool { if apid > MAX_APID { return false; @@ -645,11 +699,13 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { } /// This function sets the message counter in the PUS TM secondary header. + #[inline] pub fn set_msg_count(&mut self, msg_count: u16) { self.raw_tm[9..11].copy_from_slice(&msg_count.to_be_bytes()); } /// This function sets the destination ID in the PUS TM secondary header. + #[inline] pub fn set_destination_id(&mut self, dest_id: u16) { self.raw_tm[11..13].copy_from_slice(&dest_id.to_be_bytes()) } @@ -674,6 +730,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { /// Set the sequence count. Returns false and does not update the value if the passed value /// exceeds [MAX_SEQ_COUNT]. + #[inline] pub fn set_seq_count(&mut self, seq_count: u16) -> bool { if seq_count > MAX_SEQ_COUNT { return false; diff --git a/src/lib.rs b/src/lib.rs index 2de734a..be55af1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -207,18 +207,21 @@ pub struct PacketId { } impl PartialEq for PacketId { + #[inline] fn eq(&self, other: &Self) -> bool { self.raw().eq(&other.raw()) } } impl PartialOrd for PacketId { + #[inline] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for PacketId { + #[inline] fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.raw().cmp(&other.raw()) } @@ -232,6 +235,7 @@ impl Hash for PacketId { } impl Default for PacketId { + #[inline] fn default() -> Self { PacketId { ptype: PacketType::Tm, @@ -244,26 +248,31 @@ impl Default for PacketId { impl PacketId { /// This constructor will panic if the passed APID exceeds [MAX_APID]. /// Use the checked constructor variants to avoid panics. + #[inline] pub const fn new_for_tc(sec_header: bool, apid: u16) -> Self { Self::new(PacketType::Tc, sec_header, apid) } /// This constructor will panic if the passed APID exceeds [MAX_APID]. /// Use the checked constructor variants to avoid panics. + #[inline] pub const fn new_for_tm(sec_header: bool, apid: u16) -> Self { Self::new(PacketType::Tm, sec_header, apid) } + #[inline] pub fn new_for_tc_checked(sec_header: bool, apid: u16) -> Option { Self::new_checked(PacketType::Tc, sec_header, apid) } + #[inline] pub fn new_for_tm_checked(sec_header: bool, apid: u16) -> Option { Self::new_checked(PacketType::Tm, sec_header, apid) } /// This constructor will panic if the passed APID exceeds [MAX_APID]. /// Use the checked variants to avoid panics. + #[inline] pub const fn new(ptype: PacketType, sec_header: bool, apid: u16) -> Self { if apid > MAX_APID { panic!("APID too large"); @@ -275,6 +284,7 @@ impl PacketId { } } + #[inline] pub fn new_checked(ptype: PacketType, sec_header_flag: bool, apid: u16) -> Option { if apid > MAX_APID { return None; @@ -285,6 +295,7 @@ impl PacketId { /// Set a new Application Process ID (APID). If the passed number is invalid, the APID will /// not be set and false will be returned. The maximum allowed value for the 11-bit field is /// 2047 + #[inline] pub fn set_apid(&mut self, apid: u16) -> bool { if apid > MAX_APID { return false; @@ -293,6 +304,7 @@ impl PacketId { true } + #[inline] pub fn apid(&self) -> u16 { self.apid } @@ -326,6 +338,7 @@ pub struct PacketSequenceCtrl { impl PacketSequenceCtrl { /// This constructor panics if the sequence count exceeds [MAX_SEQ_COUNT]. /// Use [Self::new_checked] to avoid panics. + #[inline] pub const fn new(seq_flags: SequenceFlags, seq_count: u16) -> PacketSequenceCtrl { if seq_count > MAX_SEQ_COUNT { panic!("Sequence count too large"); @@ -337,18 +350,22 @@ impl PacketSequenceCtrl { } /// Returns [None] if the passed sequence count exceeds [MAX_SEQ_COUNT]. + #[inline] pub fn new_checked(seq_flags: SequenceFlags, seq_count: u16) -> Option { if seq_count > MAX_SEQ_COUNT { return None; } Some(PacketSequenceCtrl::new(seq_flags, seq_count)) } + + #[inline] pub fn raw(&self) -> u16 { ((self.seq_flags as u16) << 14) | self.seq_count } /// Set a new sequence count. If the passed number is invalid, the sequence count will not be /// set and false will be returned. The maximum allowed value for the 14-bit field is 16383. + #[inline] pub fn set_seq_count(&mut self, ssc: u16) -> bool { if ssc > MAX_SEQ_COUNT { return false; @@ -357,6 +374,7 @@ impl PacketSequenceCtrl { true } + #[inline] pub fn seq_count(&self) -> u16 { self.seq_count } @@ -398,6 +416,7 @@ pub trait CcsdsPacket { /// Retrieve data length field fn data_len(&self) -> u16; /// Retrieve the total packet size based on the data length field + #[inline] fn total_len(&self) -> usize { usize::from(self.data_len()) + CCSDS_HEADER_LEN + 1 } @@ -489,6 +508,7 @@ pub struct SpHeader { impl Default for SpHeader { /// The default function sets the sequence flag field to [SequenceFlags::Unsegmented]. The data /// length field is set to 1, which denotes an empty space packets. + #[inline] fn default() -> Self { SpHeader { version: 0, @@ -503,6 +523,7 @@ impl Default for SpHeader { } impl SpHeader { + #[inline] pub const fn new(packet_id: PacketId, psc: PacketSequenceCtrl, data_len: u16) -> Self { Self { version: 0, @@ -516,6 +537,7 @@ impl SpHeader { /// length field is set to 1, which denotes an empty space packets. /// /// This constructor will panic if the APID exceeds [MAX_APID]. + #[inline] pub const fn new_from_apid(apid: u16) -> Self { SpHeader { version: 0, @@ -529,6 +551,7 @@ impl SpHeader { } /// Checked variant of [Self::new_from_apid]. + #[inline] pub fn new_from_apid_checked(apid: u16) -> Option { Some(SpHeader { version: 0, @@ -545,6 +568,7 @@ impl SpHeader { /// count exceeds [MAX_SEQ_COUNT]. /// /// The checked constructor variants can be used to avoid panics. + #[inline] const fn new_from_fields( ptype: PacketType, sec_header: bool, @@ -572,6 +596,7 @@ impl SpHeader { /// /// This will return [None] if the APID or sequence count argument /// exceed [MAX_APID] or [MAX_SEQ_COUNT] respectively. The version field is set to 0b000. + #[inline] pub fn new_from_fields_checked( ptype: PacketType, sec_header: bool, @@ -590,6 +615,7 @@ impl SpHeader { /// Helper function for telemetry space packet headers. The packet type field will be /// set accordingly. The secondary header flag field is set to false. + #[inline] pub fn new_for_tm_checked( apid: u16, seq_flags: SequenceFlags, @@ -601,6 +627,7 @@ impl SpHeader { /// Helper function for telemetry space packet headers. The packet type field will be /// set accordingly. The secondary header flag field is set to false. + #[inline] pub fn new_for_tc_checked( apid: u16, seq_flags: SequenceFlags, @@ -611,6 +638,7 @@ impl SpHeader { } /// This is an unchecked constructor which can panic on invalid input. + #[inline] pub const fn new_for_tm( apid: u16, seq_flags: SequenceFlags, @@ -621,6 +649,7 @@ impl SpHeader { } /// This is an unchecked constructor which can panic on invalid input. + #[inline] pub const fn new_for_tc( apid: u16, seq_flags: SequenceFlags, @@ -631,11 +660,13 @@ impl SpHeader { } /// Variant of [SpHeader::new_for_tm_checked] which sets the sequence flag field to [SequenceFlags::Unsegmented] + #[inline] pub fn new_for_unseg_tm_checked(apid: u16, seq_count: u16, data_len: u16) -> Option { Self::new_for_tm_checked(apid, SequenceFlags::Unsegmented, seq_count, data_len) } /// Variant of [SpHeader::new_for_tc_checked] which sets the sequence flag field to [SequenceFlags::Unsegmented] + #[inline] pub fn new_for_unseg_tc_checked(apid: u16, seq_count: u16, data_len: u16) -> Option { Self::new_for_tc_checked(apid, SequenceFlags::Unsegmented, seq_count, data_len) } @@ -643,6 +674,7 @@ impl SpHeader { /// Variant of [SpHeader::new_for_tc] which sets the sequence flag field to [SequenceFlags::Unsegmented]. /// /// This is an unchecked constructor which can panic on invalid input. + #[inline] pub const fn new_for_unseg_tc(apid: u16, seq_count: u16, data_len: u16) -> Self { Self::new_for_tc(apid, SequenceFlags::Unsegmented, seq_count, data_len) } @@ -650,6 +682,7 @@ impl SpHeader { /// Variant of [SpHeader::new_for_tm] which sets the sequence flag field to [SequenceFlags::Unsegmented]. /// /// This is an unchecked constructor which can panic on invalid input. + #[inline] pub const fn new_for_unseg_tm(apid: u16, seq_count: u16, data_len: u16) -> Self { Self::new_for_tm(apid, SequenceFlags::Unsegmented, seq_count, data_len) } @@ -657,6 +690,7 @@ impl SpHeader { delegate! { to self.packet_id { /// Returns [false] and fails if the APID exceeds [MAX_APID] + #[inline] pub fn set_apid(&mut self, apid: u16) -> bool; } } @@ -664,22 +698,27 @@ impl SpHeader { delegate! { to self.psc { /// Returns [false] and fails if the sequence count exceeds [MAX_SEQ_COUNT] + #[inline] pub fn set_seq_count(&mut self, seq_count: u16) -> bool; } } + #[inline] pub fn set_seq_flags(&mut self, seq_flags: SequenceFlags) { self.psc.seq_flags = seq_flags; } + #[inline] pub fn set_sec_header_flag(&mut self) { self.packet_id.sec_header_flag = true; } + #[inline] pub fn clear_sec_header_flag(&mut self) { self.packet_id.sec_header_flag = false; } + #[inline] pub fn set_packet_type(&mut self, packet_type: PacketType) { self.packet_id.ptype = packet_type; } @@ -742,6 +781,7 @@ impl CcsdsPacket for SpHeader { } impl CcsdsPrimaryHeader for SpHeader { + #[inline] fn from_composite_fields( packet_id: PacketId, psc: PacketSequenceCtrl, @@ -809,9 +849,12 @@ pub mod zc { ((self.version_packet_id.get() >> 13) as u8) & 0b111 } + #[inline] fn packet_id(&self) -> PacketId { PacketId::from(self.packet_id_raw()) } + + #[inline] fn psc(&self) -> PacketSequenceCtrl { PacketSequenceCtrl::from(self.psc_raw()) } @@ -821,10 +864,12 @@ pub mod zc { self.data_len.get() } + #[inline] fn packet_id_raw(&self) -> u16 { self.version_packet_id.get() & (!VERSION_MASK) } + #[inline] fn psc_raw(&self) -> u16 { self.psc.get() } diff --git a/src/time/cds.rs b/src/time/cds.rs index b741e3c..679c6d0 100644 --- a/src/time/cds.rs +++ b/src/time/cds.rs @@ -145,6 +145,7 @@ pub fn length_of_day_segment_from_pfield(pfield: u8) -> LengthOfDaySegment { LengthOfDaySegment::Short16Bits } +#[inline] pub fn precision_from_pfield(pfield: u8) -> SubmillisPrecision { match pfield & 0b11 { 0b01 => SubmillisPrecision::Microseconds, @@ -272,24 +273,29 @@ impl ConversionFromUnix { } impl CdsCommon for ConversionFromUnix { + #[inline] fn submillis_precision(&self) -> SubmillisPrecision { self.submilis_prec } + #[inline] fn ms_of_day(&self) -> u32 { self.ms_of_day } + #[inline] fn ccsds_days_as_u32(&self) -> u32 { self.ccsds_days } + #[inline] fn submillis(&self) -> u32 { self.submillis } } impl CdsConverter for ConversionFromUnix { + #[inline] fn unix_days_seconds(&self) -> i64 { self.unix_days_seconds } @@ -302,24 +308,31 @@ struct ConversionFromChronoDatetime { } impl CdsCommon for ConversionFromChronoDatetime { + #[inline] fn submillis_precision(&self) -> SubmillisPrecision { self.submillis_prec } delegate! { to self.unix_conversion { + #[inline] fn ms_of_day(&self) -> u32; + #[inline] fn ccsds_days_as_u32(&self) -> u32; } } + #[inline] fn submillis(&self) -> u32 { self.submillis } } impl CdsConverter for ConversionFromChronoDatetime { - delegate! {to self.unix_conversion { fn unix_days_seconds(&self) -> i64; }} + delegate! {to self.unix_conversion { + #[inline] + fn unix_days_seconds(&self) -> i64; + }} } #[inline] diff --git a/src/time/cuc.rs b/src/time/cuc.rs index d798545..aec2fbc 100644 --- a/src/time/cuc.rs +++ b/src/time/cuc.rs @@ -177,6 +177,7 @@ pub struct FractionalPart { } impl FractionalPart { + #[inline] pub const fn new(resolution: FractionalResolution, counter: u32) -> Self { let div = fractional_res_to_div(resolution); assert!(counter <= div, "invalid counter for resolution"); @@ -187,15 +188,18 @@ impl FractionalPart { } /// An empty fractional part for second resolution only. + #[inline] pub const fn new_with_seconds_resolution() -> Self { Self::new(FractionalResolution::Seconds, 0) } /// Helper method which simply calls [Self::new_with_seconds_resolution]. + #[inline] pub const fn new_empty() -> Self { Self::new_with_seconds_resolution() } + #[inline] pub fn new_checked(resolution: FractionalResolution, counter: u32) -> Option { let div = fractional_res_to_div(resolution); if counter > div { @@ -207,14 +211,17 @@ impl FractionalPart { }) } + #[inline] pub fn resolution(&self) -> FractionalResolution { self.resolution } + #[inline] pub fn counter(&self) -> u32 { self.counter } + #[inline] pub fn no_fractional_part(&self) -> bool { self.resolution == FractionalResolution::Seconds } @@ -285,6 +292,7 @@ pub struct CucTimeWithLeapSecs { } impl CucTimeWithLeapSecs { + #[inline] pub fn new(time: CucTime, leap_seconds: u32) -> Self { Self { time, leap_seconds } } @@ -300,6 +308,7 @@ pub fn pfield_len(pfield: u8) -> usize { impl CucTime { /// Create a time provider with a four byte counter and no fractional part. + #[inline] pub fn new(counter: u32) -> Self { // These values are definitely valid, so it is okay to unwrap here. Self::new_generic( @@ -310,11 +319,13 @@ impl CucTime { } /// Like [CucTime::new] but allow to supply a fractional part as well. + #[inline] pub fn new_with_fractions(counter: u32, fractions: FractionalPart) -> Result { Self::new_generic(WidthCounterPair(4, counter), fractions) } /// Fractions with a resolution of ~ 4 ms + #[inline] pub fn new_with_coarse_fractions(counter: u32, subsec_fractions: u8) -> Self { // These values are definitely valid, so it is okay to unwrap here. Self::new_generic( @@ -328,6 +339,7 @@ impl CucTime { } /// Fractions with a resolution of ~ 16 us + #[inline] pub fn new_with_medium_fractions(counter: u32, subsec_fractions: u16) -> Self { // These values are definitely valid, so it is okay to unwrap here. Self::new_generic( @@ -343,6 +355,7 @@ impl CucTime { /// Fractions with a resolution of ~ 60 ns. The fractional part value is limited by the /// 24 bits of the fractional field, so this function will fail with /// [CucError::InvalidFractions] if the fractional value exceeds the value. + #[inline] pub fn new_with_fine_fractions(counter: u32, subsec_fractions: u32) -> Result { Self::new_generic( WidthCounterPair(4, counter), @@ -457,6 +470,7 @@ impl CucTime { /// Most generic constructor which allows full configurability for the counter and for the /// fractions. + #[inline] pub fn new_generic( width_and_counter: WidthCounterPair, fractions: FractionalPart, @@ -476,31 +490,38 @@ impl CucTime { }) } + #[inline] pub fn ccsds_time_code(&self) -> CcsdsTimeCode { CcsdsTimeCode::CucCcsdsEpoch } + #[inline] pub fn width_counter_pair(&self) -> WidthCounterPair { self.counter } + #[inline] pub fn counter_width(&self) -> u8 { self.counter.0 } + #[inline] pub fn counter(&self) -> u32 { self.counter.1 } /// Subsecond fractional part of the CUC time. + #[inline] pub fn fractions(&self) -> FractionalPart { self.fractions } + #[inline] pub fn to_leap_sec_helper(&self, leap_seconds: u32) -> CucTimeWithLeapSecs { CucTimeWithLeapSecs::new(*self, leap_seconds) } + #[inline] pub fn set_fractions(&mut self, fractions: FractionalPart) -> Result<(), CucError> { Self::verify_fractions_value(fractions)?; self.fractions = fractions; @@ -510,6 +531,7 @@ impl CucTime { /// Set a fractional resolution. Please note that this function will reset the fractional value /// to 0 if the resolution changes. + #[inline] pub fn set_fractional_resolution(&mut self, res: FractionalResolution) { if res == FractionalResolution::Seconds { self.fractions = FractionalPart::new_with_seconds_resolution(); @@ -519,6 +541,7 @@ impl CucTime { } } + #[inline] fn build_p_field(counter_width: u8, resolution: FractionalResolution) -> u8 { let mut pfield = P_FIELD_BASE; if !(1..=4).contains(&counter_width) { @@ -538,6 +561,7 @@ impl CucTime { pfield } + #[inline] fn update_p_field_fractions(&mut self) { self.pfield &= !(0b11); self.pfield |= self.fractions.resolution() as u8; @@ -582,6 +606,7 @@ impl CucTime { ) } + #[inline] pub fn len_packed_from_pfield(pfield: u8) -> usize { let mut base_len: usize = 1; base_len += Self::len_cntr_from_pfield(pfield) as usize; @@ -590,6 +615,7 @@ impl CucTime { } /// Verifies the raw width parameter. + #[inline] fn verify_counter_width(width: u8) -> Result<(), CucError> { if width == 0 || width > 4 { return Err(CucError::InvalidCounterWidth(width)); @@ -597,6 +623,7 @@ impl CucTime { Ok(()) } + #[inline] fn verify_fractions_value(val: FractionalPart) -> Result<(), CucError> { if val.counter > 2u32.pow((val.resolution as u32) * 8) - 1 { return Err(CucError::InvalidFractions { @@ -607,10 +634,12 @@ impl CucTime { Ok(()) } + #[inline] fn len_as_bytes(&self) -> usize { Self::len_packed_from_pfield(self.pfield) } + #[inline] fn subsec_nanos(&self) -> u32 { if self.fractions.resolution() == FractionalResolution::Seconds { return 0; @@ -751,22 +780,27 @@ impl TimeWriter for CucTime { } impl CcsdsTimeProvider for CucTimeWithLeapSecs { + #[inline] fn len_as_bytes(&self) -> usize { self.time.len_as_bytes() } + #[inline] fn p_field(&self) -> (usize, [u8; 2]) { (1, [self.time.pfield, 0]) } + #[inline] fn ccdsd_time_code(&self) -> CcsdsTimeCode { self.time.ccsds_time_code() } + #[inline] fn unix_secs(&self) -> i64 { self.time.unix_secs(self.leap_seconds) } + #[inline] fn subsec_nanos(&self) -> u32 { self.time.subsec_nanos() } diff --git a/src/time/mod.rs b/src/time/mod.rs index fe879c5..65ce745 100644 --- a/src/time/mod.rs +++ b/src/time/mod.rs @@ -166,6 +166,7 @@ pub fn seconds_since_epoch() -> f64 { /// /// - CCSDS epoch: 1958-01-01T00:00:00+00:00 /// - UNIX Epoch: 1970-01-01T00:00:00+00:00 +#[inline] pub const fn unix_to_ccsds_days(unix_days: i64) -> i64 { unix_days - DAYS_CCSDS_TO_UNIX as i64 } @@ -174,16 +175,19 @@ pub const fn unix_to_ccsds_days(unix_days: i64) -> i64 { /// /// - CCSDS epoch: 1958-01-01T00:00:00+00:00 /// - UNIX Epoch: 1970-01-01T00:00:00+00:00 +#[inline] pub const fn ccsds_to_unix_days(ccsds_days: i64) -> i64 { ccsds_days + DAYS_CCSDS_TO_UNIX as i64 } /// Similar to [unix_to_ccsds_days] but converts the epoch instead, which is the number of elpased /// seconds since the CCSDS and UNIX epoch times. +#[inline] pub const fn unix_epoch_to_ccsds_epoch(unix_epoch: i64) -> i64 { unix_epoch - (DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64) } +#[inline] pub const fn ccsds_epoch_to_unix_epoch(ccsds_epoch: i64) -> i64 { ccsds_epoch + (DAYS_CCSDS_TO_UNIX as i64 * SECONDS_PER_DAY as i64) } diff --git a/src/util.rs b/src/util.rs index 11c66b6..da80792 100644 --- a/src/util.rs +++ b/src/util.rs @@ -15,10 +15,12 @@ pub trait ToBeBytes { impl ToBeBytes for () { type ByteArray = [u8; 0]; + #[inline] fn written_len(&self) -> usize { 0 } + #[inline] fn to_be_bytes(&self) -> Self::ByteArray { [] } @@ -27,9 +29,12 @@ impl ToBeBytes for () { impl ToBeBytes for u8 { type ByteArray = [u8; 1]; + #[inline] fn written_len(&self) -> usize { 1 } + + #[inline] fn to_be_bytes(&self) -> Self::ByteArray { u8::to_be_bytes(*self) } @@ -38,9 +43,12 @@ impl ToBeBytes for u8 { impl ToBeBytes for u16 { type ByteArray = [u8; 2]; + #[inline] fn written_len(&self) -> usize { 2 } + + #[inline] fn to_be_bytes(&self) -> Self::ByteArray { u16::to_be_bytes(*self) } @@ -49,9 +57,12 @@ impl ToBeBytes for u16 { impl ToBeBytes for u32 { type ByteArray = [u8; 4]; + #[inline] fn written_len(&self) -> usize { 4 } + + #[inline] fn to_be_bytes(&self) -> Self::ByteArray { u32::to_be_bytes(*self) } @@ -60,9 +71,12 @@ impl ToBeBytes for u32 { impl ToBeBytes for u64 { type ByteArray = [u8; 8]; + #[inline] fn written_len(&self) -> usize { 8 } + + #[inline] fn to_be_bytes(&self) -> Self::ByteArray { u64::to_be_bytes(*self) } @@ -104,6 +118,7 @@ pub enum UnsignedByteFieldError { } impl From for UnsignedByteFieldError { + #[inline] fn from(value: ByteConversionError) -> Self { Self::ByteConversionError(value) } @@ -138,14 +153,17 @@ pub struct UnsignedByteField { } impl UnsignedByteField { + #[inline] pub const fn new(width: usize, value: u64) -> Self { Self { width, value } } + #[inline] pub const fn value_const(&self) -> u64 { self.value } + #[inline] pub fn new_from_be_bytes(width: usize, buf: &[u8]) -> Result { if width > buf.len() { return Err(ByteConversionError::FromSliceTooSmall { @@ -178,10 +196,12 @@ impl UnsignedByteField { } impl UnsignedEnum for UnsignedByteField { + #[inline] fn size(&self) -> usize { self.width } + #[inline] fn value(&self) -> u64 { self.value_const() } @@ -237,6 +257,7 @@ impl> GenericUnsignedByteField { } impl> UnsignedEnum for GenericUnsignedByteField { + #[inline] fn size(&self) -> usize { self.value.written_len() } @@ -252,6 +273,7 @@ impl> UnsignedEnum for GenericUnsignedByteFie Ok(self.value.written_len()) } + #[inline] fn value(&self) -> u64 { self.value_typed().into() } @@ -277,6 +299,7 @@ impl From for UnsignedByteField { impl TryFrom for UnsignedByteFieldU8 { type Error = UnsignedByteFieldError; + #[inline] fn try_from(value: UnsignedByteField) -> Result { if value.width != 1 { return Err(UnsignedByteFieldError::InvalidWidth { @@ -289,6 +312,7 @@ impl TryFrom for UnsignedByteFieldU8 { } impl From for UnsignedByteField { + #[inline] fn from(value: UnsignedByteFieldU16) -> Self { Self::new(2, value.value as u64) } @@ -297,6 +321,7 @@ impl From for UnsignedByteField { impl TryFrom for UnsignedByteFieldU16 { type Error = UnsignedByteFieldError; + #[inline] fn try_from(value: UnsignedByteField) -> Result { if value.width != 2 { return Err(UnsignedByteFieldError::InvalidWidth { @@ -309,6 +334,7 @@ impl TryFrom for UnsignedByteFieldU16 { } impl From for UnsignedByteField { + #[inline] fn from(value: UnsignedByteFieldU32) -> Self { Self::new(4, value.value as u64) } @@ -317,6 +343,7 @@ impl From for UnsignedByteField { impl TryFrom for UnsignedByteFieldU32 { type Error = UnsignedByteFieldError; + #[inline] fn try_from(value: UnsignedByteField) -> Result { if value.width != 4 { return Err(UnsignedByteFieldError::InvalidWidth { @@ -329,6 +356,7 @@ impl TryFrom for UnsignedByteFieldU32 { } impl From for UnsignedByteField { + #[inline] fn from(value: UnsignedByteFieldU64) -> Self { Self::new(8, value.value) } @@ -337,6 +365,7 @@ impl From for UnsignedByteField { impl TryFrom for UnsignedByteFieldU64 { type Error = UnsignedByteFieldError; + #[inline] fn try_from(value: UnsignedByteField) -> Result { if value.width != 8 { return Err(UnsignedByteFieldError::InvalidWidth { -- 2.43.0