bump thiserror and zerocopy

This commit is contained in:
Robin Müller 2024-11-07 23:36:04 +01:00
parent f70b957d9a
commit 48247a0a87
6 changed files with 53 additions and 76 deletions

View File

@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased] # [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 # [v0.12.0] 2024-09-10
- Bumped MSRV to 1.70.0 - Bumped MSRV to 1.70.0

View File

@ -2,7 +2,7 @@
name = "spacepackets" name = "spacepackets"
version = "0.12.0" version = "0.12.0"
edition = "2021" edition = "2021"
rust-version = "1.70.0" rust-version = "1.81.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
description = "Generic implementations for various CCSDS and ECSS packet standards" description = "Generic implementations for various CCSDS and ECSS packet standards"
homepage = "https://egit.irs.uni-stuttgart.de/rust/spacepackets" homepage = "https://egit.irs.uni-stuttgart.de/rust/spacepackets"
@ -18,12 +18,12 @@ delegate = ">=0.8, <=0.13"
paste = "1" paste = "1"
[dependencies.zerocopy] [dependencies.zerocopy]
version = "0.7" version = "0.8"
features = ["derive"] features = ["derive"]
[dependencies.thiserror] [dependencies.thiserror]
version = "1" version = "2"
optional = true default-features = false
[dependencies.num_enum] [dependencies.num_enum]
version = ">0.5, <=0.7" version = ">0.5, <=0.7"
@ -53,18 +53,16 @@ default-features = false
version = "0.3" version = "0.3"
optional = true optional = true
[dev-dependencies]
postcard = "1"
chrono = "0.4"
[features] [features]
default = ["std"] default = ["std"]
std = ["chrono/std", "chrono/clock", "alloc", "thiserror"] std = ["alloc", "chrono/std", "chrono/clock", "thiserror/std"]
serde = ["dep:serde", "chrono/serde"] serde = ["dep:serde", "chrono?/serde"]
alloc = ["postcard/alloc", "chrono/alloc", "defmt/alloc", "serde/alloc"] alloc = ["chrono?/alloc", "defmt?/alloc", "serde?/alloc"]
chrono = ["dep:chrono"]
timelib = ["dep:time"] timelib = ["dep:time"]
defmt = ["dep:defmt"]
[dev-dependencies]
postcard = { version = "1", features = ["alloc"] }
chrono = "0.4"
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true

View File

@ -45,7 +45,7 @@ use delegate::delegate;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use zerocopy::AsBytes; use zerocopy::{FromBytes, IntoBytes};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use alloc::vec::Vec; use alloc::vec::Vec;
@ -86,9 +86,9 @@ pub trait GenericPusTcSecondaryHeader {
pub mod zc { pub mod zc {
use crate::ecss::tc::GenericPusTcSecondaryHeader; use crate::ecss::tc::GenericPusTcSecondaryHeader;
use crate::ecss::{PusError, PusVersion}; 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)] #[repr(C)]
pub struct PusTcSecondaryHeader { pub struct PusTcSecondaryHeader {
version_ack: u8, version_ack: u8,
@ -138,16 +138,6 @@ pub mod zc {
self.source_id.get() 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> {
Self::read_from(slice)
}
}
} }
#[derive(PartialEq, Eq, Copy, Clone, Debug)] #[derive(PartialEq, Eq, Copy, Clone, Debug)]
@ -392,8 +382,8 @@ impl WritablePusPacket for PusTcCreator<'_> {
curr_idx += CCSDS_HEADER_LEN; curr_idx += CCSDS_HEADER_LEN;
let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap(); let sec_header = zc::PusTcSecondaryHeader::try_from(self.sec_header).unwrap();
sec_header sec_header
.write_to_bytes(&mut slice[curr_idx..curr_idx + tc_header_len]) .write_to(&mut slice[curr_idx..curr_idx + tc_header_len])
.ok_or(ByteConversionError::ZeroCopyToError)?; .map_err(|_| ByteConversionError::ZeroCopyToError)?;
curr_idx += tc_header_len; curr_idx += tc_header_len;
slice[curr_idx..curr_idx + self.app_data.len()].copy_from_slice(self.app_data); 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()); .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], &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; current_idx += PUC_TC_SECONDARY_HEADER_LEN;
let raw_data = &slice[0..total_len]; let raw_data = &slice[0..total_len];
let pus_tc = Self { let pus_tc = Self {

View File

@ -54,7 +54,7 @@ use crate::{
use core::mem::size_of; use core::mem::size_of;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use zerocopy::AsBytes; use zerocopy::{FromBytes, IntoBytes};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use alloc::vec::Vec; use alloc::vec::Vec;
@ -83,9 +83,9 @@ pub trait GenericPusTmSecondaryHeader {
pub mod zc { pub mod zc {
use super::GenericPusTmSecondaryHeader; use super::GenericPusTmSecondaryHeader;
use crate::ecss::{PusError, PusVersion}; 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)] #[repr(C)]
pub struct PusTmSecHeaderWithoutTimestamp { pub struct PusTmSecHeaderWithoutTimestamp {
pus_version_and_sc_time_ref_status: u8, 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> {
Self::read_from(slice)
}
}
impl GenericPusTmSecondaryHeader for PusTmSecHeaderWithoutTimestamp { impl GenericPusTmSecondaryHeader for PusTmSecHeaderWithoutTimestamp {
#[inline] #[inline]
fn pus_version(&self) -> PusVersion { fn pus_version(&self) -> PusVersion {
@ -413,8 +403,8 @@ impl<'time, 'src_data> PusTmCreator<'time, 'src_data> {
let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>(); let sec_header_len = size_of::<zc::PusTmSecHeaderWithoutTimestamp>();
let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap(); let sec_header = zc::PusTmSecHeaderWithoutTimestamp::try_from(self.sec_header).unwrap();
sec_header sec_header
.write_to_bytes(&mut slice[curr_idx..curr_idx + sec_header_len]) .write_to(&mut slice[curr_idx..curr_idx + sec_header_len])
.ok_or(ByteConversionError::ZeroCopyToError)?; .map_err(|_| ByteConversionError::ZeroCopyToError)?;
curr_idx += sec_header_len; curr_idx += sec_header_len;
slice[curr_idx..curr_idx + self.sec_header.timestamp.len()] slice[curr_idx..curr_idx + self.sec_header.timestamp.len()]
.copy_from_slice(self.sec_header.timestamp); .copy_from_slice(self.sec_header.timestamp);
@ -571,10 +561,10 @@ impl<'raw_data> PusTmReader<'raw_data> {
} }
.into()); .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], &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; current_idx += PUS_TM_MIN_SEC_HEADER_LEN;
let zc_sec_header_wrapper = zc::PusTmSecHeader { let zc_sec_header_wrapper = zc::PusTmSecHeader {
zc_header: sec_header_zc, 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 { if raw_tm_len < CCSDS_HEADER_LEN + PUS_TM_MIN_SEC_HEADER_LEN + timestamp_len {
return None; 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() { if raw_tm_len < sp_header.total_len() {
return None; return None;
} }
@ -751,7 +741,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> {
#[inline] #[inline]
pub fn sp_header(&self) -> crate::zc::SpHeader { pub fn sp_header(&self) -> crate::zc::SpHeader {
// Valid minimum length of packet was checked before. // 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 /// Helper API to generate the portion of the secondary header without a timestamp from the
@ -759,7 +749,7 @@ impl<'raw> PusTmZeroCopyWriter<'raw> {
#[inline] #[inline]
pub fn sec_header_without_timestamp(&self) -> PusTmSecHeaderWithoutTimestamp { pub fn sec_header_without_timestamp(&self) -> PusTmSecHeaderWithoutTimestamp {
// Valid minimum length of packet was checked before. // 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], &self.raw_tm[CCSDS_HEADER_LEN..CCSDS_HEADER_LEN + PUS_TM_MIN_SEC_HEADER_LEN],
) )
.unwrap() .unwrap()

View File

@ -67,6 +67,7 @@ use core::{
}; };
use crc::{Crc, CRC_16_IBM_3740}; use crc::{Crc, CRC_16_IBM_3740};
use delegate::delegate; use delegate::delegate;
use zerocopy::{FromBytes, IntoBytes};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error::Error; use std::error::Error;
@ -733,8 +734,8 @@ impl SpHeader {
expected: CCSDS_HEADER_LEN, expected: CCSDS_HEADER_LEN,
}); });
} }
let zc_header = zc::SpHeader::from_bytes(&buf[0..CCSDS_HEADER_LEN]) let zc_header = zc::SpHeader::read_from_bytes(&buf[0..CCSDS_HEADER_LEN])
.ok_or(ByteConversionError::ZeroCopyFromError)?; .map_err(|_| ByteConversionError::ZeroCopyFromError)?;
Ok((Self::from(zc_header), &buf[CCSDS_HEADER_LEN..])) Ok((Self::from(zc_header), &buf[CCSDS_HEADER_LEN..]))
} }
@ -752,8 +753,8 @@ impl SpHeader {
} }
let zc_header: zc::SpHeader = zc::SpHeader::from(*self); let zc_header: zc::SpHeader = zc::SpHeader::from(*self);
zc_header zc_header
.to_bytes(&mut buf[0..CCSDS_HEADER_LEN]) .write_to(&mut buf[0..CCSDS_HEADER_LEN])
.ok_or(ByteConversionError::ZeroCopyToError)?; .map_err(|_| ByteConversionError::ZeroCopyToError)?;
Ok(&mut buf[CCSDS_HEADER_LEN..]) Ok(&mut buf[CCSDS_HEADER_LEN..])
} }
@ -815,9 +816,9 @@ sph_from_other!(SpHeader, crate::zc::SpHeader);
pub mod zc { pub mod zc {
use crate::{CcsdsPacket, CcsdsPrimaryHeader, PacketId, PacketSequenceCtrl, VERSION_MASK}; use crate::{CcsdsPacket, CcsdsPrimaryHeader, PacketId, PacketSequenceCtrl, VERSION_MASK};
use zerocopy::byteorder::NetworkEndian; 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)] #[repr(C)]
pub struct SpHeader { pub struct SpHeader {
version_packet_id: U16<NetworkEndian>, version_packet_id: U16<NetworkEndian>,
@ -842,14 +843,6 @@ pub mod zc {
data_len: U16::from(data_len), data_len: U16::from(data_len),
} }
} }
pub fn from_bytes(slice: &[u8]) -> Option<Self> {
SpHeader::read_from(slice)
}
pub fn to_bytes(&self, slice: &mut [u8]) -> Option<()> {
self.write_to(slice)
}
} }
impl CcsdsPacket for SpHeader { impl CcsdsPacket for SpHeader {
@ -918,6 +911,7 @@ pub(crate) mod tests {
use postcard::{from_bytes, to_allocvec}; use postcard::{from_bytes, to_allocvec};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use zerocopy::FromBytes;
const CONST_SP: SpHeader = SpHeader::new( const CONST_SP: SpHeader = SpHeader::new(
PacketId::new_for_tc(true, 0x36), PacketId::new_for_tc(true, 0x36),
@ -1197,7 +1191,7 @@ pub(crate) mod tests {
#[test] #[test]
fn test_zc_sph() { 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) let sp_header = SpHeader::new_for_unseg_tc_checked(0x7FF, pow(2, 14) - 1, 0)
.expect("Error creating SP header"); .expect("Error creating SP header");
@ -1217,7 +1211,7 @@ pub(crate) mod tests {
assert_eq!(slice[5], 0x00); assert_eq!(slice[5], 0x00);
let mut slice = [0; 6]; 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.len(), 6);
assert_eq!(slice[0], 0x17); assert_eq!(slice[0], 0x17);
assert_eq!(slice[1], 0xFF); assert_eq!(slice[1], 0xFF);
@ -1228,7 +1222,7 @@ pub(crate) mod tests {
let mut test_vec = vec![0_u8; 6]; let mut test_vec = vec![0_u8; 6];
let slice = test_vec.as_mut_slice(); 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(); let slice = test_vec.as_slice();
assert_eq!(slice.len(), 6); assert_eq!(slice.len(), 6);
assert_eq!(slice[0], 0x17); assert_eq!(slice[0], 0x17);
@ -1238,8 +1232,8 @@ pub(crate) mod tests {
assert_eq!(slice[4], 0x00); assert_eq!(slice[4], 0x00);
assert_eq!(slice[5], 0x00); assert_eq!(slice[5], 0x00);
let sp_header = zc::SpHeader::from_bytes(slice); let sp_header = zc::SpHeader::read_from_bytes(slice);
assert!(sp_header.is_some()); assert!(sp_header.is_ok());
let sp_header = sp_header.unwrap(); let sp_header = sp_header.unwrap();
assert_eq!(sp_header.ccsds_version(), 0b000); assert_eq!(sp_header.ccsds_version(), 0b000);
assert_eq!(sp_header.packet_id_raw(), 0x17FF); assert_eq!(sp_header.packet_id_raw(), 0x17FF);

View File

@ -11,8 +11,6 @@ use core::fmt::{Debug, Display, Formatter};
use core::ops::{Add, AddAssign}; use core::ops::{Add, AddAssign};
use core::time::Duration; use core::time::Duration;
use delegate::delegate;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use super::StdTimestampError; use super::StdTimestampError;
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -300,20 +298,23 @@ impl CdsConverter for ConversionFromUnix {
self.unix_days_seconds self.unix_days_seconds
} }
} }
/// Helper struct which generates fields for the CDS time provider from a datetime. /// Helper struct which generates fields for the CDS time provider from a datetime.
#[cfg(feature = "chrono")]
struct ConversionFromChronoDatetime { struct ConversionFromChronoDatetime {
unix_conversion: ConversionFromUnix, unix_conversion: ConversionFromUnix,
submillis_prec: SubmillisPrecision, submillis_prec: SubmillisPrecision,
submillis: u32, submillis: u32,
} }
#[cfg(feature = "chrono")]
impl CdsCommon for ConversionFromChronoDatetime { impl CdsCommon for ConversionFromChronoDatetime {
#[inline] #[inline]
fn submillis_precision(&self) -> SubmillisPrecision { fn submillis_precision(&self) -> SubmillisPrecision {
self.submillis_prec self.submillis_prec
} }
delegate! { delegate::delegate! {
to self.unix_conversion { to self.unix_conversion {
#[inline] #[inline]
fn ms_of_day(&self) -> u32; fn ms_of_day(&self) -> u32;
@ -328,8 +329,9 @@ impl CdsCommon for ConversionFromChronoDatetime {
} }
} }
#[cfg(feature = "chrono")]
impl CdsConverter for ConversionFromChronoDatetime { impl CdsConverter for ConversionFromChronoDatetime {
delegate! {to self.unix_conversion { delegate::delegate! {to self.unix_conversion {
#[inline] #[inline]
fn unix_days_seconds(&self) -> i64; fn unix_days_seconds(&self) -> i64;
}} }}
@ -366,7 +368,6 @@ impl ConversionFromChronoDatetime {
Self::new_generic(dt, SubmillisPrecision::Picoseconds) Self::new_generic(dt, SubmillisPrecision::Picoseconds)
} }
#[cfg(feature = "chrono")]
fn new_generic( fn new_generic(
dt: &chrono::DateTime<chrono::Utc>, dt: &chrono::DateTime<chrono::Utc>,
prec: SubmillisPrecision, prec: SubmillisPrecision,
@ -448,7 +449,7 @@ impl CdsCommon for ConversionFromNow {
fn submillis_precision(&self) -> SubmillisPrecision { fn submillis_precision(&self) -> SubmillisPrecision {
self.submillis_prec self.submillis_prec
} }
delegate! { delegate::delegate! {
to self.unix_conversion { to self.unix_conversion {
fn ms_of_day(&self) -> u32; fn ms_of_day(&self) -> u32;
fn ccsds_days_as_u32(&self) -> u32; fn ccsds_days_as_u32(&self) -> u32;
@ -462,7 +463,7 @@ impl CdsCommon for ConversionFromNow {
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl CdsConverter for ConversionFromNow { 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")] #[cfg(feature = "alloc")]