seems to compile
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good

This commit is contained in:
Robin Müller 2024-02-01 23:38:09 +01:00
parent 7c32b1c905
commit 145b50347d
Signed by: muellerr
GPG Key ID: A649FB78196E3849

View File

@ -2,13 +2,14 @@
//! //!
//! The core data structure of this module is the [PusScheduler]. This structure can be used //! The core data structure of this module is the [PusScheduler]. This structure can be used
//! to perform the scheduling of telecommands like specified in the ECSS standard. //! to perform the scheduling of telecommands like specified in the ECSS standard.
use core::fmt::Debug; use core::fmt::{Debug, Display, Formatter};
use core::time::Duration;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use spacepackets::ecss::scheduling::TimeWindowType; use spacepackets::ecss::scheduling::TimeWindowType;
use spacepackets::ecss::tc::{GenericPusTcSecondaryHeader, IsPusTelecommand, PusTcReader}; use spacepackets::ecss::tc::{GenericPusTcSecondaryHeader, IsPusTelecommand, PusTcReader};
use spacepackets::ecss::PusPacket; use spacepackets::ecss::{PusError, PusPacket};
use spacepackets::time::{CcsdsTimeProvider, TimeReader, UnixTimestamp}; use spacepackets::time::{CcsdsTimeProvider, TimeReader, TimestampError, UnixTimestamp};
use spacepackets::CcsdsPacket; use spacepackets::CcsdsPacket;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error::Error; use std::error::Error;
@ -136,6 +137,86 @@ impl<TimeProvider: CcsdsTimeProvider + Clone> TimeWindow<TimeProvider> {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ScheduleError {
PusError(PusError),
/// The release time is within the time-margin added on top of the current time.
/// The first parameter is the current time, the second one the time margin, and the third one
/// the release time.
ReleaseTimeInTimeMargin {
current_time: UnixTimestamp,
time_margin: Duration,
release_time: UnixTimestamp,
},
/// Nested time-tagged commands are not allowed.
NestedScheduledTc,
StoreError(StoreError),
TcDataEmpty,
TimestampError(TimestampError),
WrongSubservice,
WrongService,
}
impl Display for ScheduleError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
ScheduleError::PusError(e) => {
write!(f, "Pus Error: {e}")
}
ScheduleError::ReleaseTimeInTimeMargin {
current_time,
time_margin,
release_time,
} => {
write!(
f,
"Error: time margin too short, current time: {current_time:?}, time margin: {time_margin:?}, release time: {release_time:?}"
)
}
ScheduleError::NestedScheduledTc => {
write!(f, "Error: nested scheduling is not allowed")
}
ScheduleError::StoreError(e) => {
write!(f, "Store Error: {e}")
}
ScheduleError::TcDataEmpty => {
write!(f, "Error: empty Tc Data field")
}
ScheduleError::TimestampError(e) => {
write!(f, "Timestamp Error: {e}")
}
ScheduleError::WrongService => {
write!(f, "Error: Service not 11.")
}
ScheduleError::WrongSubservice => {
write!(f, "Error: Subservice not 4.")
}
}
}
}
impl From<PusError> for ScheduleError {
fn from(e: PusError) -> Self {
ScheduleError::PusError(e)
}
}
impl From<StoreError> for ScheduleError {
fn from(e: StoreError) -> Self {
ScheduleError::StoreError(e)
}
}
impl From<TimestampError> for ScheduleError {
fn from(e: TimestampError) -> Self {
ScheduleError::TimestampError(e)
}
}
#[cfg(feature = "std")]
impl Error for ScheduleError {}
pub trait PusSchedulerInterface { pub trait PusSchedulerInterface {
type TimeProvider: CcsdsTimeProvider + TimeReader; type TimeProvider: CcsdsTimeProvider + TimeReader;
@ -213,13 +294,12 @@ pub mod alloc_mod {
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::fmt::{Display, Formatter};
use core::time::Duration; use core::time::Duration;
use spacepackets::ecss::scheduling::TimeWindowType; use spacepackets::ecss::scheduling::TimeWindowType;
use spacepackets::ecss::tc::{PusTc, PusTcReader}; use spacepackets::ecss::tc::{PusTc, PusTcReader};
use spacepackets::ecss::{PusError, PusPacket}; use spacepackets::ecss::PusPacket;
use spacepackets::time::cds::DaysLen24Bits; use spacepackets::time::cds::DaysLen24Bits;
use spacepackets::time::{cds, CcsdsTimeProvider, TimestampError, UnixTimestamp}; use spacepackets::time::{cds, CcsdsTimeProvider, UnixTimestamp};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::time::SystemTimeError; use std::time::SystemTimeError;
@ -229,78 +309,6 @@ pub mod alloc_mod {
WithStoreDeletion(Result<bool, StoreError>), WithStoreDeletion(Result<bool, StoreError>),
} }
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ScheduleError {
PusError(PusError),
/// The release time is within the time-margin added on top of the current time.
/// The first parameter is the current time, the second one the time margin, and the third one
/// the release time.
ReleaseTimeInTimeMargin(UnixTimestamp, Duration, UnixTimestamp),
/// Nested time-tagged commands are not allowed.
NestedScheduledTc,
StoreError(StoreError),
TcDataEmpty,
TimestampError(TimestampError),
WrongSubservice,
WrongService,
}
impl Display for ScheduleError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
ScheduleError::PusError(e) => {
write!(f, "Pus Error: {e}")
}
ScheduleError::ReleaseTimeInTimeMargin(current_time, margin, timestamp) => {
write!(
f,
"Error: time margin too short, current time: {current_time:?}, time margin: {margin:?}, release time: {timestamp:?}"
)
}
ScheduleError::NestedScheduledTc => {
write!(f, "Error: nested scheduling is not allowed")
}
ScheduleError::StoreError(e) => {
write!(f, "Store Error: {e}")
}
ScheduleError::TcDataEmpty => {
write!(f, "Error: empty Tc Data field")
}
ScheduleError::TimestampError(e) => {
write!(f, "Timestamp Error: {e}")
}
ScheduleError::WrongService => {
write!(f, "Error: Service not 11.")
}
ScheduleError::WrongSubservice => {
write!(f, "Error: Subservice not 4.")
}
}
}
}
impl From<PusError> for ScheduleError {
fn from(e: PusError) -> Self {
ScheduleError::PusError(e)
}
}
impl From<StoreError> for ScheduleError {
fn from(e: StoreError) -> Self {
ScheduleError::StoreError(e)
}
}
impl From<TimestampError> for ScheduleError {
fn from(e: TimestampError) -> Self {
ScheduleError::TimestampError(e)
}
}
#[cfg(feature = "std")]
impl Error for ScheduleError {}
/// This is the core data structure for scheduling PUS telecommands with [alloc] support. /// This is the core data structure for scheduling PUS telecommands with [alloc] support.
/// ///
/// It is assumed that the actual telecommand data is stored in a separate TC pool offering /// It is assumed that the actual telecommand data is stored in a separate TC pool offering
@ -378,11 +386,11 @@ pub mod alloc_mod {
info: TcInfo, info: TcInfo,
) -> Result<(), ScheduleError> { ) -> Result<(), ScheduleError> {
if time_stamp < self.current_time + self.time_margin { if time_stamp < self.current_time + self.time_margin {
return Err(ScheduleError::ReleaseTimeInTimeMargin( return Err(ScheduleError::ReleaseTimeInTimeMargin {
self.current_time, current_time: self.current_time,
self.time_margin, time_margin: self.time_margin,
time_stamp, release_time: time_stamp,
)); });
} }
match self.tc_map.entry(time_stamp) { match self.tc_map.entry(time_stamp) {
Entry::Vacant(e) => { Entry::Vacant(e) => {
@ -672,11 +680,11 @@ pub mod alloc_mod {
info: TcInfo, info: TcInfo,
) -> Result<(), ScheduleError> { ) -> Result<(), ScheduleError> {
if time_stamp < self.current_time + self.time_margin { if time_stamp < self.current_time + self.time_margin {
return Err(ScheduleError::ReleaseTimeInTimeMargin( return Err(ScheduleError::ReleaseTimeInTimeMargin {
self.current_time, current_time: self.current_time,
self.time_margin, time_margin: self.time_margin,
time_stamp, release_time: time_stamp,
)); });
} }
match self.tc_map.entry(time_stamp) { match self.tc_map.entry(time_stamp) {
Entry::Vacant(e) => { Entry::Vacant(e) => {
@ -1324,9 +1332,13 @@ mod tests {
assert!(insert_res.is_err()); assert!(insert_res.is_err());
let err = insert_res.unwrap_err(); let err = insert_res.unwrap_err();
match err { match err {
ScheduleError::ReleaseTimeInTimeMargin(curr_time, margin, release_time) => { ScheduleError::ReleaseTimeInTimeMargin {
assert_eq!(curr_time, UnixTimestamp::new_only_seconds(0)); current_time,
assert_eq!(margin, Duration::from_secs(5)); time_margin,
release_time,
} => {
assert_eq!(current_time, UnixTimestamp::new_only_seconds(0));
assert_eq!(time_margin, Duration::from_secs(5));
assert_eq!(release_time, UnixTimestamp::new_only_seconds(4)); assert_eq!(release_time, UnixTimestamp::new_only_seconds(4));
} }
_ => panic!("unexepcted error {err}"), _ => panic!("unexepcted error {err}"),