6 Commits

Author SHA1 Message Date
256407432d create release checklist
All checks were successful
Rust/spacepackets/pipeline/head This commit looks good
2023-01-22 13:06:22 +01:00
c59b015a20 added additional tests
All checks were successful
Rust/spacepackets/pipeline/head This commit looks good
2023-01-22 12:53:39 +01:00
e081504b33 Merge branch 'main' of https://egit.irs.uni-stuttgart.de/rust/spacepackets
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit
2023-01-22 12:51:23 +01:00
6eb1b1efbc bugfix, additional test and CHANGELOG bump 2023-01-22 12:50:49 +01:00
51d0a08e7b better document panics and tweak Add/AddAssign impl
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit
for UnixTimestamp
2023-01-22 01:54:41 +01:00
6e557c2568 add Add impls for &
All checks were successful
Rust/spacepackets/pipeline/head This commit looks good
2023-01-21 14:50:35 +01:00
6 changed files with 111 additions and 7 deletions

View File

@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased]
# [v0.5.1] 2023-01-22
## Added
- `time::cds::TimeProvider`
@ -20,6 +22,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Add `Ord` and `PartialOrd` implementations.
- Add `Add<Duration>` and `AddAssign<Duration>` implementations.
## Fixed
- `time::cds::TimeProvider`: Fixed a big where subsecond milliseconds were not accounted for
when the provider has no submillisecond precision.
# [v0.5.0] 2023-01-20
The timestamp of `PusTm` is now optional. See Added and Changed section for details.

View File

@ -1,6 +1,6 @@
[package]
name = "spacepackets"
version = "0.5.0"
version = "0.5.1"
edition = "2021"
rust-version = "1.60"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]

18
release_checklist.md Normal file
View File

@ -0,0 +1,18 @@
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`.
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. Run `cargo test --all-features`.
5. Run `cargo fmt` and `cargo clippy`. Check `cargo msrv` against MSRV in `Cargo.toml`.
6. Wait for CI/CD results for EGit and Github. These also check cross-compilation for bare-metal
targets.
# Post-Release
1. Create a new release on `EGit` based on the release branch.

View File

@ -996,8 +996,14 @@ fn add_for_max_ccsds_days_val<T: ProvidesDaysLength>(
_ => None,
}
} else {
increment_ms_of_day(
&mut next_ms_of_day,
duration.subsec_millis(),
&mut next_ccsds_days,
);
None
};
// The subsecond millisecond were already handled.
let full_seconds = duration.as_secs();
let secs_of_day = (full_seconds % SECONDS_PER_DAY as u64) as u32;
let ms_of_day = secs_of_day * 1000;
@ -1038,6 +1044,20 @@ impl Add<Duration> for TimeProvider<DaysLen16Bits> {
}
}
impl Add<Duration> for &TimeProvider<DaysLen16Bits> {
type Output = TimeProvider<DaysLen16Bits>;
fn add(self, duration: Duration) -> Self::Output {
let (next_ccsds_days, next_ms_of_day, precision) =
add_for_max_ccsds_days_val(self, u16::MAX as u32, duration);
let mut provider = Self::Output::new_with_u16_days(next_ccsds_days as u16, next_ms_of_day);
if let Some(prec) = precision {
provider.set_submillis_precision(prec);
}
provider
}
}
/// Allows adding an duration in form of an offset. Please note that the CCSDS days will rollover
/// when they overflow, because addition needs to be infallible. The user needs to check for a
/// days overflow when this is a possibility and might be a problem.
@ -1055,6 +1075,20 @@ impl Add<Duration> for TimeProvider<DaysLen24Bits> {
}
}
impl Add<Duration> for &TimeProvider<DaysLen24Bits> {
type Output = TimeProvider<DaysLen24Bits>;
fn add(self, duration: Duration) -> Self::Output {
let (next_ccsds_days, next_ms_of_day, precision) =
add_for_max_ccsds_days_val(self, MAX_DAYS_24_BITS, duration);
let mut provider =
Self::Output::new_with_u24_days(next_ccsds_days, next_ms_of_day).unwrap();
if let Some(prec) = precision {
provider.set_submillis_precision(prec);
}
provider
}
}
/// Allows adding an duration in form of an offset. Please note that the CCSDS days will rollover
/// when they overflow, because addition needs to be infallible. The user needs to check for a
/// days overflow when this is a possibility and might be a problem.
@ -2074,6 +2108,16 @@ mod tests {
}
}
#[test]
fn test_addition_on_ref() {
// This test case also tests the case where there is no submillis precision but subsecond
// milliseconds.
let provider_ref = &TimeProvider::new_with_u16_days(2, 500);
let new_stamp = provider_ref + Duration::from_millis(2 * 24 * 60 * 60 * 1000 + 500);
assert_eq!(new_stamp.ccsds_days_as_u32(), 4);
assert_eq!(new_stamp.ms_of_day, 1000);
}
fn check_ps_and_carryover(prec: SubmillisPrecision, ms_of_day: u32, val: u32) {
if let SubmillisPrecision::Picoseconds(ps) = prec {
assert_eq!(ps, val);

View File

@ -696,6 +696,20 @@ impl Add<Duration> for TimeProviderCcsdsEpoch {
}
}
impl Add<Duration> for &TimeProviderCcsdsEpoch {
type Output = TimeProviderCcsdsEpoch;
fn add(self, duration: Duration) -> Self::Output {
let (new_counter, new_fractional_part) =
get_provider_values_after_duration_addition(self, duration);
if let Some(fractional_part) = new_fractional_part {
// The generated fractional part should always be valid, so its okay to unwrap here.
return Self::Output::new_with_fractions(new_counter, fractional_part).unwrap();
}
Self::Output::new(new_counter)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -367,14 +367,14 @@ fn get_new_stamp_after_addition(
let mut new_subsec_millis =
current_stamp.subsecond_millis().unwrap_or(0) + duration.subsec_millis() as u16;
let mut new_unix_seconds = current_stamp.unix_seconds;
let mut increment_seconds = |value: u64| {
let mut increment_seconds = |value: u32| {
if new_unix_seconds < 0 {
new_unix_seconds = new_unix_seconds
.checked_sub_unsigned(value)
.checked_sub(value.into())
.expect("new unix seconds would exceed i64::MIN");
} else {
new_unix_seconds = new_unix_seconds
.checked_add_unsigned(value)
.checked_add(value.into())
.expect("new unix seconds would exceed i64::MAX");
}
};
@ -382,18 +382,31 @@ fn get_new_stamp_after_addition(
new_subsec_millis -= 1000;
increment_seconds(1);
}
increment_seconds(duration.as_secs());
increment_seconds(
duration
.as_secs()
.try_into()
.expect("duration seconds exceeds u32::MAX"),
);
UnixTimestamp::const_new(new_unix_seconds, new_subsec_millis)
}
/// Please note that this operation will panic if the unix seconds after subtraction (for stamps
/// before the unix epoch) exceeds [i64::MIN] or exceeds [i64::MAX] after addition.
/// Please note that this operation will panic on the following conditions:
///
/// - Unix seconds after subtraction for stamps before the unix epoch exceeds [i64::MIN].
/// - Unix seconds after addition exceeds [i64::MAX].
/// - Seconds from duration to add exceeds [u32::MAX].
impl AddAssign<Duration> for UnixTimestamp {
fn add_assign(&mut self, duration: Duration) {
*self = get_new_stamp_after_addition(self, duration);
}
}
/// Please note that this operation will panic for the following conditions:
///
/// - Unix seconds after subtraction for stamps before the unix epoch exceeds [i64::MIN].
/// - Unix seconds after addition exceeds [i64::MAX].
/// - Unix seconds exceeds [u32::MAX].
impl Add<Duration> for UnixTimestamp {
type Output = Self;
@ -526,6 +539,14 @@ mod tests {
assert_eq!(stamp1.subsecond_millis().unwrap(), 500);
}
#[test]
fn test_addition_on_ref() {
let stamp0 = &UnixTimestamp::new(20, 500).unwrap();
let stamp1 = stamp0 + Duration::from_millis(2500);
assert_eq!(stamp1.unix_seconds, 23);
assert!(stamp1.subsecond_millis().is_none());
}
#[test]
fn test_addition_spillover() {
let mut stamp0 = UnixTimestamp::new(1, 900).unwrap();