diff --git a/CHANGELOG.md b/CHANGELOG.md index f783ef5..29d7729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). # [unreleased] +- Bumped MSRV to 1.81.0 +- Bump `zerocopy` to v0.8.0 +- Bump `thiserror` to v2.0.0 + # [v0.12.0] 2024-09-10 - Bumped MSRV to 1.70.0 diff --git a/Cargo.toml b/Cargo.toml index 2b2821d..3058346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "spacepackets" version = "0.12.0" edition = "2021" -rust-version = "1.70.0" +rust-version = "1.81.0" authors = ["Robin Mueller "] description = "Generic implementations for various CCSDS and ECSS packet standards" homepage = "https://egit.irs.uni-stuttgart.de/rust/spacepackets" @@ -18,12 +18,12 @@ delegate = ">=0.8, <=0.13" paste = "1" [dependencies.zerocopy] -version = "0.7" +version = "0.8" features = ["derive"] [dependencies.thiserror] -version = "1" -optional = true +version = "2" +default-features = false [dependencies.num_enum] version = ">0.5, <=0.7" @@ -53,18 +53,16 @@ default-features = false version = "0.3" optional = true -[dev-dependencies] -postcard = "1" -chrono = "0.4" - [features] default = ["std"] -std = ["chrono/std", "chrono/clock", "alloc", "thiserror"] -serde = ["dep:serde", "chrono/serde"] -alloc = ["postcard/alloc", "chrono/alloc", "defmt/alloc", "serde/alloc"] -chrono = ["dep:chrono"] +std = ["alloc", "chrono/std", "chrono/clock", "thiserror/std"] +serde = ["dep:serde", "chrono?/serde"] +alloc = ["chrono?/alloc", "defmt?/alloc", "serde?/alloc"] timelib = ["dep:time"] -defmt = ["dep:defmt"] + +[dev-dependencies] +postcard = { version = "1", features = ["alloc"] } +chrono = "0.4" [package.metadata.docs.rs] all-features = true diff --git a/src/ecss/tc.rs b/src/ecss/tc.rs index 7aa3069..20ebe1a 100644 --- a/src/ecss/tc.rs +++ b/src/ecss/tc.rs @@ -45,7 +45,7 @@ use delegate::delegate; use num_enum::{IntoPrimitive, TryFromPrimitive}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use zerocopy::AsBytes; +use zerocopy::{FromBytes, IntoBytes}; #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -86,9 +86,9 @@ pub trait GenericPusTcSecondaryHeader { pub mod zc { use crate::ecss::tc::GenericPusTcSecondaryHeader; use crate::ecss::{PusError, PusVersion}; - use zerocopy::{AsBytes, FromBytes, FromZeroes, NetworkEndian, Unaligned, U16}; + use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, Unaligned, U16}; - #[derive(FromZeroes, FromBytes, AsBytes, Unaligned)] + #[derive(FromBytes, IntoBytes, Immutable, Unaligned)] #[repr(C)] pub struct PusTcSecondaryHeader { version_ack: u8, @@ -138,16 +138,6 @@ pub mod zc { self.source_id.get() } } - - impl PusTcSecondaryHeader { - pub fn write_to_bytes(&self, slice: &mut [u8]) -> Option<()> { - self.write_to(slice) - } - - pub fn from_bytes(slice: &[u8]) -> Option { - Self::read_from(slice) - } - } } #[derive(PartialEq, Eq, Copy, Clone, Debug)] @@ -392,8 +382,8 @@ impl WritablePusPacket for PusTcCreator<'_> { curr_idx += CCSDS_HEADER_LEN; let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap(); sec_header - .write_to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len]) - .ok_or(ByteConversionError::ZeroCopyToError)?; + .write_to(&mut slice[curr_idx..curr_idx + tc_header_len]) + .map_err(|_| ByteConversionError::ZeroCopyToError)?; curr_idx += tc_header_len; slice[curr_idx..curr_idx + self.app_data.len()].copy_from_slice(self.app_data); @@ -502,10 +492,10 @@ impl<'raw_data> PusTcReader<'raw_data> { } .into()); } - let sec_header = zc::PusTcSecondaryHeader::from_bytes( + let sec_header = zc::PusTcSecondaryHeader::read_from_bytes( &slice[current_idx..current_idx + PUC_TC_SECONDARY_HEADER_LEN], ) - .ok_or(ByteConversionError::ZeroCopyFromError)?; + .map_err(|_| ByteConversionError::ZeroCopyFromError)?; current_idx += PUC_TC_SECONDARY_HEADER_LEN; let raw_data = &slice[0..total_len]; let pus_tc = Self { diff --git a/src/ecss/tm.rs b/src/ecss/tm.rs index 63a4f0e..d552ae9 100644 --- a/src/ecss/tm.rs +++ b/src/ecss/tm.rs @@ -54,7 +54,7 @@ use crate::{ use core::mem::size_of; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use zerocopy::AsBytes; +use zerocopy::{FromBytes, IntoBytes}; #[cfg(feature = "alloc")] use alloc::vec::Vec; @@ -83,9 +83,9 @@ pub trait GenericPusTmSecondaryHeader { pub mod zc { use super::GenericPusTmSecondaryHeader; use crate::ecss::{PusError, PusVersion}; - use zerocopy::{AsBytes, FromBytes, FromZeroes, NetworkEndian, Unaligned, U16}; + use zerocopy::{FromBytes, Immutable, IntoBytes, NetworkEndian, Unaligned, U16}; - #[derive(FromBytes, FromZeroes, AsBytes, Unaligned)] + #[derive(FromBytes, IntoBytes, Immutable, Unaligned)] #[repr(C)] pub struct PusTmSecHeaderWithoutTimestamp { pus_version_and_sc_time_ref_status: u8, @@ -117,16 +117,6 @@ pub mod zc { } } - impl PusTmSecHeaderWithoutTimestamp { - pub fn write_to_bytes(&self, slice: &mut [u8]) -> Option<()> { - self.write_to(slice) - } - - pub fn from_bytes(slice: &[u8]) -> Option { - Self::read_from(slice) - } - } - impl GenericPusTmSecondaryHeader for PusTmSecHeaderWithoutTimestamp { #[inline] fn pus_version(&self) -> PusVersion { @@ -413,8 +403,8 @@ impl<'time, 'src_data> PusTmCreator<'time, 'src_data> { let sec_header_len = size_of::(); let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap(); sec_header - .write_to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len]) - .ok_or(ByteConversionError::ZeroCopyToError)?; + .write_to(&mut slice[curr_idx..curr_idx + sec_header_len]) + .map_err(|_| ByteConversionError::ZeroCopyToError)?; curr_idx += sec_header_len; slice[curr_idx..curr_idx + self.sec_header.timestamp.len()] .copy_from_slice(self.sec_header.timestamp); @@ -571,10 +561,10 @@ impl<'raw_data> PusTmReader<'raw_data> { } .into()); } - let sec_header_zc = zc::PusTmSecHeaderWithoutTimestamp::from_bytes( + let sec_header_zc = zc::PusTmSecHeaderWithoutTimestamp::read_from_bytes( &slice[current_idx..current_idx + PUS_TM_MIN_SEC_HEADER_LEN], ) - .ok_or(ByteConversionError::ZeroCopyFromError)?; + .map_err(|_| ByteConversionError::ZeroCopyFromError)?; current_idx += PUS_TM_MIN_SEC_HEADER_LEN; let zc_sec_header_wrapper = zc::PusTmSecHeader { zc_header: sec_header_zc, @@ -710,7 +700,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { if raw_tm_len < CCSDS_HEADER_LEN + PUS_TM_MIN_SEC_HEADER_LEN + timestamp_len { return None; } - let sp_header = crate::zc::SpHeader::from_bytes(&raw_tm[0..CCSDS_HEADER_LEN]).unwrap(); + let sp_header = crate::zc::SpHeader::read_from_bytes(&raw_tm[0..CCSDS_HEADER_LEN]).unwrap(); if raw_tm_len < sp_header.total_len() { return None; } @@ -751,7 +741,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { #[inline] pub fn sp_header(&self) -> crate::zc::SpHeader { // Valid minimum length of packet was checked before. - crate::zc::SpHeader::from_bytes(&self.raw_tm[0..CCSDS_HEADER_LEN]).unwrap() + crate::zc::SpHeader::read_from_bytes(&self.raw_tm[0..CCSDS_HEADER_LEN]).unwrap() } /// Helper API to generate the portion of the secondary header without a timestamp from the @@ -759,7 +749,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> { #[inline] pub fn sec_header_without_timestamp(&self) -> PusTmSecHeaderWithoutTimestamp { // Valid minimum length of packet was checked before. - PusTmSecHeaderWithoutTimestamp::from_bytes( + PusTmSecHeaderWithoutTimestamp::read_from_bytes( &self.raw_tm[CCSDS_HEADER_LEN..CCSDS_HEADER_LEN + PUS_TM_MIN_SEC_HEADER_LEN], ) .unwrap() diff --git a/src/lib.rs b/src/lib.rs index 0271b69..bdb1fd9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,7 @@ use core::{ }; use crc::{Crc, CRC_16_IBM_3740}; use delegate::delegate; +use zerocopy::{FromBytes, IntoBytes}; #[cfg(feature = "std")] use std::error::Error; @@ -733,8 +734,8 @@ impl SpHeader { expected: CCSDS_HEADER_LEN, }); } - let zc_header = zc::SpHeader::from_bytes(&buf[0..CCSDS_HEADER_LEN]) - .ok_or(ByteConversionError::ZeroCopyFromError)?; + let zc_header = zc::SpHeader::read_from_bytes(&buf[0..CCSDS_HEADER_LEN]) + .map_err(|_| ByteConversionError::ZeroCopyFromError)?; Ok((Self::from(zc_header), &buf[CCSDS_HEADER_LEN..])) } @@ -752,8 +753,8 @@ impl SpHeader { } let zc_header: zc::SpHeader = zc::SpHeader::from(*self); zc_header - .to_bytes(&mut buf[0..CCSDS_HEADER_LEN]) - .ok_or(ByteConversionError::ZeroCopyToError)?; + .write_to(&mut buf[0..CCSDS_HEADER_LEN]) + .map_err(|_| ByteConversionError::ZeroCopyToError)?; Ok(&mut buf[CCSDS_HEADER_LEN..]) } @@ -815,9 +816,9 @@ sph_from_other!(SpHeader, crate::zc::SpHeader); pub mod zc { use crate::{CcsdsPacket, CcsdsPrimaryHeader, PacketId, PacketSequenceCtrl, VERSION_MASK}; use zerocopy::byteorder::NetworkEndian; - use zerocopy::{AsBytes, FromBytes, FromZeroes, Unaligned, U16}; + use zerocopy::{FromBytes, Immutable, IntoBytes, Unaligned, U16}; - #[derive(FromBytes, FromZeroes, AsBytes, Unaligned, Debug)] + #[derive(FromBytes, IntoBytes, Immutable, Unaligned, Debug)] #[repr(C)] pub struct SpHeader { version_packet_id: U16, @@ -842,14 +843,6 @@ pub mod zc { data_len: U16::from(data_len), } } - - pub fn from_bytes(slice: &[u8]) -> Option { - SpHeader::read_from(slice) - } - - pub fn to_bytes(&self, slice: &mut [u8]) -> Option<()> { - self.write_to(slice) - } } impl CcsdsPacket for SpHeader { @@ -918,6 +911,7 @@ pub(crate) mod tests { use postcard::{from_bytes, to_allocvec}; #[cfg(feature = "serde")] use serde::{de::DeserializeOwned, Serialize}; + use zerocopy::FromBytes; const CONST_SP: SpHeader = SpHeader::new( PacketId::new_for_tc(true, 0x36), @@ -1197,7 +1191,7 @@ pub(crate) mod tests { #[test] fn test_zc_sph() { - use zerocopy::AsBytes; + use zerocopy::IntoBytes; let sp_header = SpHeader::new_for_unseg_tc_checked(0x7FF, pow(2, 14) - 1, 0) .expect("Error creating SP header"); @@ -1217,7 +1211,7 @@ pub(crate) mod tests { assert_eq!(slice[5], 0x00); let mut slice = [0; 6]; - sp_header_zc.write_to(slice.as_mut_slice()); + sp_header_zc.write_to(slice.as_mut_slice()).unwrap(); assert_eq!(slice.len(), 6); assert_eq!(slice[0], 0x17); assert_eq!(slice[1], 0xFF); @@ -1228,7 +1222,7 @@ pub(crate) mod tests { let mut test_vec = vec![0_u8; 6]; let slice = test_vec.as_mut_slice(); - sp_header_zc.write_to(slice); + sp_header_zc.write_to(slice).unwrap(); let slice = test_vec.as_slice(); assert_eq!(slice.len(), 6); assert_eq!(slice[0], 0x17); @@ -1238,8 +1232,8 @@ pub(crate) mod tests { assert_eq!(slice[4], 0x00); assert_eq!(slice[5], 0x00); - let sp_header = zc::SpHeader::from_bytes(slice); - assert!(sp_header.is_some()); + let sp_header = zc::SpHeader::read_from_bytes(slice); + assert!(sp_header.is_ok()); let sp_header = sp_header.unwrap(); assert_eq!(sp_header.ccsds_version(), 0b000); assert_eq!(sp_header.packet_id_raw(), 0x17FF); diff --git a/src/time/cds.rs b/src/time/cds.rs index 84833bb..9b7eb94 100644 --- a/src/time/cds.rs +++ b/src/time/cds.rs @@ -11,8 +11,6 @@ use core::fmt::{Debug, Display, Formatter}; use core::ops::{Add, AddAssign}; use core::time::Duration; -use delegate::delegate; - #[cfg(feature = "std")] use super::StdTimestampError; #[cfg(feature = "std")] @@ -300,20 +298,23 @@ impl CdsConverter for ConversionFromUnix { self.unix_days_seconds } } + /// Helper struct which generates fields for the CDS time provider from a datetime. +#[cfg(feature = "chrono")] struct ConversionFromChronoDatetime { unix_conversion: ConversionFromUnix, submillis_prec: SubmillisPrecision, submillis: u32, } +#[cfg(feature = "chrono")] impl CdsCommon for ConversionFromChronoDatetime { #[inline] fn submillis_precision(&self) -> SubmillisPrecision { self.submillis_prec } - delegate! { + delegate::delegate! { to self.unix_conversion { #[inline] fn ms_of_day(&self) -> u32; @@ -328,8 +329,9 @@ impl CdsCommon for ConversionFromChronoDatetime { } } +#[cfg(feature = "chrono")] impl CdsConverter for ConversionFromChronoDatetime { - delegate! {to self.unix_conversion { + delegate::delegate! {to self.unix_conversion { #[inline] fn unix_days_seconds(&self) -> i64; }} @@ -366,7 +368,6 @@ impl ConversionFromChronoDatetime { Self::new_generic(dt, SubmillisPrecision::Picoseconds) } - #[cfg(feature = "chrono")] fn new_generic( dt: &chrono::DateTime, prec: SubmillisPrecision, @@ -448,7 +449,7 @@ impl CdsCommon for ConversionFromNow { fn submillis_precision(&self) -> SubmillisPrecision { self.submillis_prec } - delegate! { + delegate::delegate! { to self.unix_conversion { fn ms_of_day(&self) -> u32; fn ccsds_days_as_u32(&self) -> u32; @@ -462,7 +463,7 @@ impl CdsCommon for ConversionFromNow { #[cfg(feature = "std")] impl CdsConverter for ConversionFromNow { - delegate! {to self.unix_conversion { fn unix_days_seconds(&self) -> i64; }} + delegate::delegate! {to self.unix_conversion { fn unix_days_seconds(&self) -> i64; }} } #[cfg(feature = "alloc")]