use alloc::vec::Vec;
use core::{convert::Infallible as Never, fmt::Debug};
use crate::{
sync::DynDebugReferences,
testutil::{
FakeCryptoRng, FakeEventCtx, FakeFrameCtx, FakeInstantCtx, FakeTimerCtx,
WithFakeTimerContext,
},
ContextProvider, DeferredResourceRemovalContext, EventContext, ReferenceNotifiers, RngContext,
TimerBindingsTypes, TimerContext, TracingContext,
};
pub struct FakeBindingsCtx<TimerId, Event: Debug, State, FrameMeta> {
pub rng: FakeCryptoRng,
pub timers: FakeTimerCtx<TimerId>,
pub events: FakeEventCtx<Event>,
pub frames: FakeFrameCtx<FrameMeta>,
pub state: State,
}
impl<TimerId, Event: Debug, State, FrameMeta> ContextProvider
for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
{
type Context = Self;
fn context(&mut self) -> &mut Self::Context {
self
}
}
impl<TimerId, Event: Debug, State: Default, FrameMeta> Default
for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
{
fn default() -> Self {
Self {
rng: FakeCryptoRng::new_xorshift(0),
timers: FakeTimerCtx::default(),
events: FakeEventCtx::default(),
frames: FakeFrameCtx::default(),
state: Default::default(),
}
}
}
impl<TimerId, Event: Debug, State, FrameMeta> FakeBindingsCtx<TimerId, Event, State, FrameMeta> {
pub fn seed_rng(&mut self, seed: u128) {
self.rng = FakeCryptoRng::new_xorshift(seed);
}
pub fn take_events(&mut self) -> Vec<Event> {
self.events.take()
}
}
impl<TimerId, Event: Debug, State, FrameMeta> RngContext
for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
{
type Rng<'a> = FakeCryptoRng where Self: 'a;
fn rng(&mut self) -> Self::Rng<'_> {
self.rng.clone()
}
}
impl<Id, Event: Debug, State, FrameMeta> AsRef<FakeInstantCtx>
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn as_ref(&self) -> &FakeInstantCtx {
self.timers.as_ref()
}
}
impl<Id, Event: Debug, State, FrameMeta> AsRef<FakeTimerCtx<Id>>
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn as_ref(&self) -> &FakeTimerCtx<Id> {
&self.timers
}
}
impl<Id, Event: Debug, State, FrameMeta> AsMut<FakeTimerCtx<Id>>
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn as_mut(&mut self) -> &mut FakeTimerCtx<Id> {
&mut self.timers
}
}
impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta> TimerBindingsTypes
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
type Timer = <FakeTimerCtx<Id> as TimerBindingsTypes>::Timer;
type DispatchId = <FakeTimerCtx<Id> as TimerBindingsTypes>::DispatchId;
}
impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta> TimerContext
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn new_timer(&mut self, id: Self::DispatchId) -> Self::Timer {
self.timers.new_timer(id)
}
fn schedule_timer_instant(
&mut self,
time: Self::Instant,
timer: &mut Self::Timer,
) -> Option<Self::Instant> {
self.timers.schedule_timer_instant(time, timer)
}
fn cancel_timer(&mut self, timer: &mut Self::Timer) -> Option<Self::Instant> {
self.timers.cancel_timer(timer)
}
fn scheduled_instant(&self, timer: &mut Self::Timer) -> Option<Self::Instant> {
self.timers.scheduled_instant(timer)
}
}
impl<Id, Event: Debug, State, FrameMeta> EventContext<Event>
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn on_event(&mut self, event: Event) {
self.events.on_event(event)
}
}
impl<Id, Event: Debug, State, FrameMeta> TracingContext
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
type DurationScope = ();
fn duration(&self, _: &'static core::ffi::CStr) {}
}
impl<Id, Event: Debug, State, FrameMeta> ReferenceNotifiers
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
type ReferenceReceiver<T: 'static> = Never;
type ReferenceNotifier<T: Send + 'static> = Never;
fn new_reference_notifier<T: Send + 'static>(
debug_references: DynDebugReferences,
) -> (Self::ReferenceNotifier<T>, Self::ReferenceReceiver<T>) {
panic!(
"FakeBindingsCtx can't create deferred reference notifiers for type {}: \
debug_references={debug_references:?}",
core::any::type_name::<T>()
);
}
}
impl<Id, Event: Debug, State, FrameMeta> DeferredResourceRemovalContext
for FakeBindingsCtx<Id, Event, State, FrameMeta>
{
fn defer_removal<T: Send + 'static>(&mut self, receiver: Self::ReferenceReceiver<T>) {
match receiver {}
}
}
impl<TimerId, Event: Debug, State, FrameMeta> WithFakeTimerContext<TimerId>
for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
{
fn with_fake_timer_ctx<O, F: FnOnce(&FakeTimerCtx<TimerId>) -> O>(&self, f: F) -> O {
f(&self.timers)
}
fn with_fake_timer_ctx_mut<O, F: FnOnce(&mut FakeTimerCtx<TimerId>) -> O>(
&mut self,
f: F,
) -> O {
f(&mut self.timers)
}
}