From 48247a0a8786d71dd9ec8d7e0ca536a337cb0612 Mon Sep 17 00:00:00 2001
From: Robin Mueller <robin.mueller.m@gmail.com>
Date: Thu, 7 Nov 2024 23:36:04 +0100
Subject: [PATCH] bump thiserror and zerocopy

---
 CHANGELOG.md    |  4 ++++
 Cargo.toml      | 24 +++++++++++-------------
 src/ecss/tc.rs  | 24 +++++++-----------------
 src/ecss/tm.rs  | 30 ++++++++++--------------------
 src/lib.rs      | 32 +++++++++++++-------------------
 src/time/cds.rs | 15 ++++++++-------
 6 files changed, 53 insertions(+), 76 deletions(-)

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 <muellerr@irs.uni-stuttgart.de>"]
 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> {
-            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> {
-            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::<zc::PusTmSecHeaderWithoutTimestamp>();
         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<NetworkEndian>,
@@ -842,14 +843,6 @@ pub mod zc {
                 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 {
@@ -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<chrono::Utc>,
         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")]