make new abstractions more generic
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
All checks were successful
Rust/sat-rs/pipeline/pr-main This commit looks good
This commit is contained in:
parent
c6f2dde138
commit
b0d32aff4f
@ -71,19 +71,6 @@ pub struct ActiveActionRequest {
|
||||
common: ActiveRequest,
|
||||
}
|
||||
|
||||
pub trait ActiveRequestMapProvider: Default {
|
||||
fn insert(&mut self, request_id: &RequestId, request: ActiveActionRequest);
|
||||
fn get(&self, request_id: RequestId) -> Option<&ActiveActionRequest>;
|
||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut ActiveActionRequest>;
|
||||
fn remove(&mut self, request_id: RequestId) -> bool;
|
||||
|
||||
/// Call a user-supplied closure for each active request.
|
||||
fn for_each<F: FnMut(&RequestId, &ActiveActionRequest)>(&self, f: F);
|
||||
|
||||
/// Call a user-supplied closure for each active request. Mutable variant.
|
||||
fn for_each_mut<F: FnMut(&RequestId, &mut ActiveActionRequest)>(&mut self, f: F);
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
|
||||
pub mod alloc_mod {
|
||||
@ -130,9 +117,10 @@ pub mod std_mod {
|
||||
verification::{
|
||||
self, FailParams, FailParamsWithStep, TcStateStarted, VerificationReportingProvider,
|
||||
},
|
||||
EcssTcInMemConverter, EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError,
|
||||
GenericRoutingError, PusPacketHandlerResult, PusPacketHandlingError,
|
||||
PusRoutingErrorHandler, PusServiceHelper,
|
||||
ActiveRequestMapProvider, DefaultActiveRequestMap, EcssTcInMemConverter,
|
||||
EcssTcReceiverCore, EcssTmSenderCore, EcssTmtcError, GenericRoutingError,
|
||||
PusPacketHandlerResult, PusPacketHandlingError, PusRoutingErrorHandler,
|
||||
PusServiceHelper,
|
||||
},
|
||||
request::RequestId,
|
||||
};
|
||||
@ -250,38 +238,7 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DefaultActiveRequestMap(HashMap<RequestId, ActiveActionRequest>);
|
||||
|
||||
impl ActiveRequestMapProvider for DefaultActiveRequestMap {
|
||||
fn insert(&mut self, request_id: &RequestId, request: ActiveActionRequest) {
|
||||
self.0.insert(*request_id, request);
|
||||
}
|
||||
|
||||
fn get(&self, request_id: RequestId) -> Option<&ActiveActionRequest> {
|
||||
self.0.get(&request_id)
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut ActiveActionRequest> {
|
||||
self.0.get_mut(&request_id)
|
||||
}
|
||||
|
||||
fn remove(&mut self, request_id: RequestId) -> bool {
|
||||
self.0.remove(&request_id).is_some()
|
||||
}
|
||||
|
||||
fn for_each<F: FnMut(&RequestId, &ActiveActionRequest)>(&self, mut f: F) {
|
||||
for (req_id, active_req) in &self.0 {
|
||||
f(req_id, active_req);
|
||||
}
|
||||
}
|
||||
|
||||
fn for_each_mut<F: FnMut(&RequestId, &mut ActiveActionRequest)>(&mut self, mut f: F) {
|
||||
for (req_id, active_req) in &mut self.0 {
|
||||
f(req_id, active_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub type DefaultActiveActionRequestMap = DefaultActiveRequestMap<ActiveActionRequest>;
|
||||
|
||||
pub trait ActionReplyHandlerHook {
|
||||
fn handle_unexpected_reply(&mut self, reply: &ActionReplyPusWithIds);
|
||||
@ -291,10 +248,10 @@ pub mod std_mod {
|
||||
|
||||
pub struct PusService8ReplyHandler<
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
ActiveRequestMap: ActiveRequestMapProvider,
|
||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
||||
UserHook: ActionReplyHandlerHook,
|
||||
> {
|
||||
active_requests: ActiveRequestMap,
|
||||
active_request_map: ActiveRequestMap,
|
||||
verification_reporter: VerificationReporter,
|
||||
fail_data_buf: alloc::vec::Vec<u8>,
|
||||
current_time: UnixTimestamp,
|
||||
@ -303,20 +260,22 @@ pub mod std_mod {
|
||||
|
||||
impl<
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
ActiveRequestMap: ActiveRequestMapProvider,
|
||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveActionRequest>,
|
||||
UserHook: ActionReplyHandlerHook,
|
||||
> PusService8ReplyHandler<VerificationReporter, ActiveRequestMap, UserHook>
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
pub fn new_with_init_time_now(
|
||||
pub fn new_from_now(
|
||||
verification_reporter: VerificationReporter,
|
||||
active_request_map: ActiveRequestMap,
|
||||
fail_data_buf_size: usize,
|
||||
user_hook: UserHook,
|
||||
) -> Result<Self, SystemTimeError> {
|
||||
let current_time = UnixTimestamp::from_now()?;
|
||||
Ok(Self::new(
|
||||
verification_reporter,
|
||||
active_request_map,
|
||||
fail_data_buf_size,
|
||||
user_hook,
|
||||
current_time,
|
||||
@ -325,18 +284,20 @@ pub mod std_mod {
|
||||
|
||||
pub fn new(
|
||||
verification_reporter: VerificationReporter,
|
||||
active_request_map: ActiveRequestMap,
|
||||
fail_data_buf_size: usize,
|
||||
user_hook: UserHook,
|
||||
init_time: UnixTimestamp,
|
||||
) -> Self {
|
||||
Self {
|
||||
active_requests: ActiveRequestMap::default(),
|
||||
active_request_map,
|
||||
verification_reporter,
|
||||
fail_data_buf: alloc::vec![0; fail_data_buf_size],
|
||||
current_time: init_time,
|
||||
user_hook,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_routed_request(
|
||||
&mut self,
|
||||
request_id: verification::RequestId,
|
||||
@ -344,7 +305,7 @@ pub mod std_mod {
|
||||
token: VerificationToken<TcStateStarted>,
|
||||
timeout: Duration,
|
||||
) {
|
||||
self.active_requests.insert(
|
||||
self.active_request_map.insert(
|
||||
&request_id.into(),
|
||||
ActiveActionRequest {
|
||||
action_id,
|
||||
@ -358,7 +319,7 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
pub fn request_active(&self, request_id: RequestId) -> bool {
|
||||
self.active_requests.get(request_id).is_some()
|
||||
self.active_request_map.get(request_id).is_some()
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@ -373,7 +334,7 @@ pub mod std_mod {
|
||||
/// It will call [Self::handle_timeout] for all active requests which have timed out.
|
||||
pub fn check_for_timeouts(&mut self, time_stamp: &[u8]) -> Result<(), EcssTmtcError> {
|
||||
let mut timed_out_commands = alloc::vec::Vec::new();
|
||||
self.active_requests.for_each(|request_id, active_req| {
|
||||
self.active_request_map.for_each(|request_id, active_req| {
|
||||
let diff = self.current_time - active_req.common.start_time;
|
||||
if diff.duration_absolute > active_req.common.timeout {
|
||||
self.handle_timeout(active_req, time_stamp);
|
||||
@ -381,7 +342,7 @@ pub mod std_mod {
|
||||
timed_out_commands.push(*request_id);
|
||||
});
|
||||
for timed_out_command in timed_out_commands {
|
||||
self.active_requests.remove(timed_out_command);
|
||||
self.active_request_map.remove(timed_out_command);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -412,7 +373,9 @@ pub mod std_mod {
|
||||
action_reply_with_ids: ActionReplyPusWithIds,
|
||||
time_stamp: &[u8],
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let active_req = self.active_requests.get(action_reply_with_ids.request_id);
|
||||
let active_req = self
|
||||
.active_request_map
|
||||
.get(action_reply_with_ids.request_id);
|
||||
if active_req.is_none() {
|
||||
self.user_hook
|
||||
.handle_unexpected_reply(&action_reply_with_ids);
|
||||
@ -468,12 +431,47 @@ pub mod std_mod {
|
||||
}
|
||||
};
|
||||
if remove_entry {
|
||||
self.active_requests
|
||||
self.active_request_map
|
||||
.remove(action_reply_with_ids.request_id);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<VerificationReporter: VerificationReportingProvider, UserHook: ActionReplyHandlerHook>
|
||||
PusService8ReplyHandler<VerificationReporter, DefaultActiveActionRequestMap, UserHook>
|
||||
{
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
|
||||
pub fn new_from_now_with_default_map(
|
||||
verification_reporter: VerificationReporter,
|
||||
fail_data_buf_size: usize,
|
||||
user_hook: UserHook,
|
||||
) -> Result<Self, SystemTimeError> {
|
||||
let current_time = UnixTimestamp::from_now()?;
|
||||
Ok(Self::new_with_default_map(
|
||||
verification_reporter,
|
||||
fail_data_buf_size,
|
||||
user_hook,
|
||||
current_time,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_with_default_map(
|
||||
verification_reporter: VerificationReporter,
|
||||
fail_data_buf_size: usize,
|
||||
user_hook: UserHook,
|
||||
init_time: UnixTimestamp,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
verification_reporter,
|
||||
DefaultActiveRequestMap::<ActiveActionRequest>(HashMap::default()),
|
||||
fail_data_buf_size,
|
||||
user_hook,
|
||||
init_time,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -670,7 +668,7 @@ mod tests {
|
||||
verif_reporter: TestVerificationReporter,
|
||||
handler: PusService8ReplyHandler<
|
||||
TestVerificationReporter,
|
||||
DefaultActiveRequestMap,
|
||||
DefaultActiveActionRequestMap,
|
||||
TestReplyHandlerHook,
|
||||
>,
|
||||
}
|
||||
@ -680,7 +678,7 @@ mod tests {
|
||||
let reply_handler_hook = TestReplyHandlerHook::default();
|
||||
let shared_verif_map = SharedVerificationMap::default();
|
||||
let test_verif_reporter = TestVerificationReporter::new(shared_verif_map.clone());
|
||||
let reply_handler = PusService8ReplyHandler::new_with_init_time_now(
|
||||
let reply_handler = PusService8ReplyHandler::new_from_now_with_default_map(
|
||||
test_verif_reporter.clone(),
|
||||
128,
|
||||
reply_handler_hook,
|
||||
|
@ -5,12 +5,15 @@
|
||||
use crate::pool::{StoreAddr, StoreError};
|
||||
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
||||
use crate::queue::{GenericReceiveError, GenericSendError};
|
||||
use crate::request::RequestId;
|
||||
use crate::ChannelId;
|
||||
use core::fmt::{Display, Formatter};
|
||||
use core::time::Duration;
|
||||
#[cfg(feature = "alloc")]
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
#[cfg(feature = "alloc")]
|
||||
use dyn_clone::DynClone;
|
||||
use spacepackets::time::UnixTimestamp;
|
||||
#[cfg(feature = "std")]
|
||||
use std::error::Error;
|
||||
|
||||
@ -39,6 +42,8 @@ pub use alloc_mod::*;
|
||||
#[cfg(feature = "std")]
|
||||
pub use std_mod::*;
|
||||
|
||||
use self::verification::TcStateStarted;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PusTmWrapper<'tm> {
|
||||
InStore(StoreAddr),
|
||||
@ -270,8 +275,30 @@ pub trait ReceivesEcssPusTc {
|
||||
fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTcReader) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
pub trait ActiveRequestMapProvider<V>: Sized {
|
||||
fn insert(&mut self, request_id: &RequestId, request: V);
|
||||
fn get(&self, request_id: RequestId) -> Option<&V>;
|
||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut V>;
|
||||
fn remove(&mut self, request_id: RequestId) -> bool;
|
||||
|
||||
/// Call a user-supplied closure for each active request.
|
||||
fn for_each<F: FnMut(&RequestId, &V)>(&self, f: F);
|
||||
|
||||
/// Call a user-supplied closure for each active request. Mutable variant.
|
||||
fn for_each_mut<F: FnMut(&RequestId, &mut V)>(&mut self, f: F);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ActiveRequest {
|
||||
token: VerificationToken<TcStateStarted>,
|
||||
start_time: UnixTimestamp,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
mod alloc_mod {
|
||||
use hashbrown::HashMap;
|
||||
|
||||
use crate::TargetId;
|
||||
|
||||
use super::*;
|
||||
@ -370,6 +397,39 @@ mod alloc_mod {
|
||||
verif_reporter: &impl VerificationReportingProvider,
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct DefaultActiveRequestMap<V>(pub HashMap<RequestId, V>);
|
||||
|
||||
impl<V> ActiveRequestMapProvider<V> for DefaultActiveRequestMap<V> {
|
||||
fn insert(&mut self, request_id: &RequestId, request: V) {
|
||||
self.0.insert(*request_id, request);
|
||||
}
|
||||
|
||||
fn get(&self, request_id: RequestId) -> Option<&V> {
|
||||
self.0.get(&request_id)
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut V> {
|
||||
self.0.get_mut(&request_id)
|
||||
}
|
||||
|
||||
fn remove(&mut self, request_id: RequestId) -> bool {
|
||||
self.0.remove(&request_id).is_some()
|
||||
}
|
||||
|
||||
fn for_each<F: FnMut(&RequestId, &V)>(&self, mut f: F) {
|
||||
for (req_id, active_req) in &self.0 {
|
||||
f(req_id, active_req);
|
||||
}
|
||||
}
|
||||
|
||||
fn for_each_mut<F: FnMut(&RequestId, &mut V)>(&mut self, mut f: F) {
|
||||
for (req_id, active_req) in &mut self.0 {
|
||||
f(req_id, active_req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user