Compare commits
18 Commits
v0.7.0-bet
...
v0.7.0-bet
Author | SHA1 | Date | |
---|---|---|---|
34b58fe9cc | |||
393c73cedf
|
|||
3e97bf0c15
|
|||
7839fb3776 | |||
55ad24db34
|
|||
3b4a909ce1 | |||
76ad1c7ead | |||
79d26e1a67 | |||
be37c15478
|
|||
a6bced7983
|
|||
5d8b5ce370
|
|||
b94d07f6c9
|
|||
90e48483bb
|
|||
963b9dbb5f
|
|||
2a0db6b21c
|
|||
a4b14250c2
|
|||
6116cdb27c
|
|||
6ebdf7e330
|
@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
## Added
|
||||
|
||||
- `PacketId` trait impls: `Ord`, `PartialOrd` and `Hash`
|
||||
- `SerializablePusPacket` trait: Add `to_vec` method with default implementation.
|
||||
|
||||
# [v0.7.0-beta.1] 2023-08-28
|
||||
|
||||
- Bump `zerocopy` dependency to v0.7.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "spacepackets"
|
||||
version = "0.7.0-beta.1"
|
||||
version = "0.7.0-beta.2"
|
||||
edition = "2021"
|
||||
rust-version = "1.61"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
|
5
automation/Jenkinsfile
vendored
5
automation/Jenkinsfile
vendored
@ -8,6 +8,11 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Rust Toolchain Info') {
|
||||
steps {
|
||||
sh 'rustc --version'
|
||||
}
|
||||
}
|
||||
stage('Clippy') {
|
||||
steps {
|
||||
sh 'cargo clippy'
|
||||
|
@ -4,7 +4,7 @@ Checklist for new releases
|
||||
# Pre-Release
|
||||
|
||||
1. Make sure any new modules are documented sufficiently enough and check docs with
|
||||
`cargo doc --all-features --open`.
|
||||
`cargo +nightly doc --all-features --open`.
|
||||
2. Bump version specifier in `Cargo.toml`.
|
||||
3. Update `CHANGELOG.md`: Convert `unreleased` section into version section with date and add new
|
||||
`unreleased` section.
|
||||
|
@ -4,6 +4,8 @@
|
||||
//! You can find the PUS telecommand definitions in the [tc] module and ithe PUS telemetry definitions
|
||||
//! inside the [tm] module.
|
||||
use crate::{ByteConversionError, CcsdsPacket, CRC_CCITT_FALSE};
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use core::mem::size_of;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
@ -361,6 +363,15 @@ pub type EcssEnumU64 = GenericEcssEnumWrapper<u64>;
|
||||
pub trait SerializablePusPacket {
|
||||
fn len_packed(&self) -> usize;
|
||||
fn write_to_bytes(&self, slice: &mut [u8]) -> Result<usize, PusError>;
|
||||
#[cfg(feature = "alloc")]
|
||||
fn to_vec(&self) -> Result<Vec<u8>, PusError> {
|
||||
// This is the correct way to do this. See
|
||||
// [this issue](https://github.com/rust-lang/rust-clippy/issues/4483) for caveats of more
|
||||
// "efficient" implementations.
|
||||
let mut vec = alloc::vec![0; self.len_packed()];
|
||||
self.write_to_bytes(&mut vec)?;
|
||||
Ok(vec)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
53
src/lib.rs
53
src/lib.rs
@ -62,7 +62,10 @@ extern crate alloc;
|
||||
extern crate std;
|
||||
|
||||
use crate::ecss::CCSDS_HEADER_LEN;
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use core::{
|
||||
fmt::{Debug, Display, Formatter},
|
||||
hash::Hash,
|
||||
};
|
||||
use crc::{Crc, CRC_16_IBM_3740};
|
||||
use delegate::delegate;
|
||||
|
||||
@ -187,7 +190,7 @@ impl TryFrom<u8> for SequenceFlags {
|
||||
|
||||
/// Abstraction for the CCSDS Packet ID, which forms the last thirteen bits
|
||||
/// of the first two bytes in the CCSDS primary header.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(Debug, Eq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct PacketId {
|
||||
pub ptype: PacketType,
|
||||
@ -195,6 +198,31 @@ pub struct PacketId {
|
||||
apid: u16,
|
||||
}
|
||||
|
||||
impl PartialEq for PacketId {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.raw().eq(&other.raw())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for PacketId {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
|
||||
self.raw().partial_cmp(&other.raw())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for PacketId {
|
||||
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||
self.raw().cmp(&other.raw())
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for PacketId {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
let raw = self.raw();
|
||||
raw.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PacketId {
|
||||
fn default() -> Self {
|
||||
PacketId {
|
||||
@ -255,6 +283,7 @@ impl PacketId {
|
||||
self.apid
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn raw(&self) -> u16 {
|
||||
((self.ptype as u16) << 12) | ((self.sec_header_flag as u16) << 11) | self.apid
|
||||
}
|
||||
@ -721,6 +750,8 @@ pub mod zc {
|
||||
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
use crate::CcsdsPrimaryHeader;
|
||||
use crate::{
|
||||
@ -1034,4 +1065,22 @@ mod tests {
|
||||
assert_eq!(sp_header.ptype(), PacketType::Tc);
|
||||
assert_eq!(sp_header.data_len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn packet_id_ord_partial_ord() {
|
||||
let packet_id_small = PacketId::from(1_u16);
|
||||
let packet_id_larger = PacketId::from(2_u16);
|
||||
assert!(packet_id_small < packet_id_larger);
|
||||
assert!(packet_id_larger > packet_id_small);
|
||||
assert_eq!(
|
||||
packet_id_small.cmp(&packet_id_larger),
|
||||
core::cmp::Ordering::Less
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn packet_id_hashable() {
|
||||
let mut id_set = HashSet::new();
|
||||
id_set.insert(PacketId::from(1_u16));
|
||||
}
|
||||
}
|
||||
|
@ -1716,11 +1716,12 @@ mod tests {
|
||||
}
|
||||
|
||||
fn generic_dt_case_0_no_prec(subsec_millis: u32) -> DateTime<Utc> {
|
||||
let naivedatetime_utc = NaiveDate::from_ymd_opt(2023, 01, 14)
|
||||
NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
.unwrap()
|
||||
.and_hms_milli_opt(16, 49, 30, subsec_millis)
|
||||
.unwrap();
|
||||
DateTime::<Utc>::from_utc(naivedatetime_utc, Utc)
|
||||
.unwrap()
|
||||
.and_local_timezone(Utc)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn generic_check_dt_case_0<DaysLen: ProvidesDaysLength>(
|
||||
@ -1764,11 +1765,12 @@ mod tests {
|
||||
fn generic_dt_case_1_us_prec(subsec_millis: u32) -> DateTime<Utc> {
|
||||
// 250 ms + 500 us
|
||||
let subsec_micros = subsec_millis * 1000 + 500;
|
||||
let naivedatetime_utc = NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
.unwrap()
|
||||
.and_hms_micro_opt(16, 49, 30, subsec_micros)
|
||||
.unwrap();
|
||||
DateTime::<Utc>::from_utc(naivedatetime_utc, Utc)
|
||||
.unwrap()
|
||||
.and_local_timezone(Utc)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn generic_check_dt_case_1_us_prec<DaysLen: ProvidesDaysLength>(
|
||||
@ -1815,12 +1817,13 @@ mod tests {
|
||||
// 250 ms + 500 us
|
||||
let subsec_nanos = subsec_millis * 1000 * 1000 + 500 * 1000;
|
||||
let submilli_nanos = subsec_nanos % 10_u32.pow(6);
|
||||
let naivedatetime_utc = NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
.unwrap()
|
||||
.and_hms_nano_opt(16, 49, 30, subsec_nanos)
|
||||
.unwrap();
|
||||
(
|
||||
DateTime::<Utc>::from_utc(naivedatetime_utc, Utc),
|
||||
NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
.unwrap()
|
||||
.and_hms_nano_opt(16, 49, 30, subsec_nanos)
|
||||
.unwrap()
|
||||
.and_local_timezone(Utc)
|
||||
.unwrap(),
|
||||
submilli_nanos,
|
||||
)
|
||||
}
|
||||
@ -1903,11 +1906,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_creation_from_unix_stamp_1() {
|
||||
let subsec_millis = 250;
|
||||
let naivedatetime_utc = NaiveDate::from_ymd_opt(2023, 01, 14)
|
||||
let datetime_utc = NaiveDate::from_ymd_opt(2023, 1, 14)
|
||||
.unwrap()
|
||||
.and_hms_milli_opt(16, 49, 30, subsec_millis)
|
||||
.unwrap()
|
||||
.and_local_timezone(Utc)
|
||||
.unwrap();
|
||||
let datetime_utc = DateTime::<Utc>::from_utc(naivedatetime_utc, Utc);
|
||||
let time_provider = TimeProvider::from_unix_secs_with_u16_days(&datetime_utc.into())
|
||||
.expect("creating provider from unix stamp failed");
|
||||
// https://www.timeanddate.com/date/durationresult.html?d1=01&m1=01&y1=1958&d2=14&m2=01&y2=2023
|
||||
@ -2185,11 +2189,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_from_dt_invalid_time() {
|
||||
// Date before CCSDS epoch
|
||||
let naivedatetime_utc = NaiveDate::from_ymd_opt(1957, 12, 31)
|
||||
let datetime_utc = NaiveDate::from_ymd_opt(1957, 12, 31)
|
||||
.unwrap()
|
||||
.and_hms_milli_opt(23, 59, 59, 999)
|
||||
.unwrap()
|
||||
.and_local_timezone(Utc)
|
||||
.unwrap();
|
||||
let datetime_utc = DateTime::<Utc>::from_utc(naivedatetime_utc, Utc);
|
||||
let time_provider = TimeProvider::from_dt_with_u24_days(&datetime_utc);
|
||||
assert!(time_provider.is_err());
|
||||
if let TimestampError::DateBeforeCcsdsEpoch(dt) = time_provider.unwrap_err() {
|
||||
@ -2204,8 +2209,8 @@ mod tests {
|
||||
stamp0.write_to_bytes(&mut buf).unwrap();
|
||||
let stamp1 = TimeProvider::from_bytes_with_u16_days(&buf).unwrap();
|
||||
assert_eq!(stamp0, stamp1);
|
||||
assert!(!(stamp0 < stamp1));
|
||||
assert!(!(stamp1 > stamp0));
|
||||
assert!(stamp0 >= stamp1);
|
||||
assert!(stamp1 <= stamp0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Reference in New Issue
Block a user