1use alloc::vec::Vec;
8use core::convert::Infallible as Never;
9use core::fmt::Debug;
10
11use crate::sync::DynDebugReferences;
12use crate::testutil::{
13 AlwaysDefaultsSettingsContext, FakeAtomicInstant, FakeCryptoRng, FakeEventCtx, FakeFrameCtx,
14 FakeInstant, FakeTimerCtx, WithFakeTimerContext,
15};
16use crate::{
17 ContextProvider, DeferredResourceRemovalContext, EventContext, InstantBindingsTypes,
18 InstantContext, MatcherBindingsTypes, ReferenceNotifiers, RngContext, TimerBindingsTypes,
19 TimerContext,
20};
21
22pub struct FakeBindingsCtx<TimerId, Event: Debug, State, FrameMeta> {
24 pub rng: FakeCryptoRng,
26 pub timers: FakeTimerCtx<TimerId>,
28 pub events: FakeEventCtx<Event>,
30 pub frames: FakeFrameCtx<FrameMeta>,
32 pub state: State,
34}
35
36impl<TimerId, Event: Debug, State, FrameMeta> ContextProvider
37 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
38{
39 type Context = Self;
40 fn context(&mut self) -> &mut Self::Context {
41 self
42 }
43}
44
45impl<TimerId, Event: Debug, State: Default, FrameMeta> Default
46 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
47{
48 fn default() -> Self {
49 Self {
50 rng: FakeCryptoRng::new_xorshift(0),
51 timers: FakeTimerCtx::default(),
52 events: FakeEventCtx::default(),
53 frames: FakeFrameCtx::default(),
54 state: Default::default(),
55 }
56 }
57}
58
59impl<TimerId, Event: Debug, State, FrameMeta> FakeBindingsCtx<TimerId, Event, State, FrameMeta> {
60 pub fn seed_rng(&mut self, seed: u128) {
62 self.rng = FakeCryptoRng::new_xorshift(seed);
63 }
64
65 pub fn take_events(&mut self) -> Vec<Event> {
67 self.events.take()
68 }
69}
70
71impl<TimerId, Event: Debug, State, FrameMeta> RngContext
72 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
73{
74 type Rng<'a>
75 = FakeCryptoRng
76 where
77 Self: 'a;
78
79 fn rng(&mut self) -> Self::Rng<'_> {
80 self.rng.clone()
81 }
82}
83
84impl<TimerId, Event: Debug, State, FrameMeta> InstantBindingsTypes
85 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
86{
87 type Instant = FakeInstant;
88 type AtomicInstant = FakeAtomicInstant;
89}
90
91impl<TimerId, Event: Debug, State, FrameMeta> InstantContext
92 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
93{
94 fn now(&self) -> Self::Instant {
95 self.timers.now()
96 }
97}
98
99impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta> TimerBindingsTypes
100 for FakeBindingsCtx<Id, Event, State, FrameMeta>
101{
102 type Timer = <FakeTimerCtx<Id> as TimerBindingsTypes>::Timer;
103 type DispatchId = <FakeTimerCtx<Id> as TimerBindingsTypes>::DispatchId;
104 type UniqueTimerId = <FakeTimerCtx<Id> as TimerBindingsTypes>::UniqueTimerId;
105}
106
107impl<Id: Debug + PartialEq + Clone + Send + Sync, Event: Debug, State, FrameMeta> TimerContext
108 for FakeBindingsCtx<Id, Event, State, FrameMeta>
109{
110 fn new_timer(&mut self, id: Self::DispatchId) -> Self::Timer {
111 self.timers.new_timer(id)
112 }
113
114 fn schedule_timer_instant(
115 &mut self,
116 time: Self::Instant,
117 timer: &mut Self::Timer,
118 ) -> Option<Self::Instant> {
119 self.timers.schedule_timer_instant(time, timer)
120 }
121
122 fn cancel_timer(&mut self, timer: &mut Self::Timer) -> Option<Self::Instant> {
123 self.timers.cancel_timer(timer)
124 }
125
126 fn scheduled_instant(&self, timer: &mut Self::Timer) -> Option<Self::Instant> {
127 self.timers.scheduled_instant(timer)
128 }
129
130 fn unique_timer_id(&self, timer: &Self::Timer) -> Self::UniqueTimerId {
131 self.timers.unique_timer_id(timer)
132 }
133}
134
135impl<Id, Event: Debug, State, FrameMeta> EventContext<Event>
136 for FakeBindingsCtx<Id, Event, State, FrameMeta>
137{
138 fn on_event(&mut self, event: Event) {
139 self.events.on_event(event)
140 }
141}
142
143impl<Id, Event: Debug, State, FrameMeta> ReferenceNotifiers
144 for FakeBindingsCtx<Id, Event, State, FrameMeta>
145{
146 type ReferenceReceiver<T: 'static> = Never;
147
148 type ReferenceNotifier<T: Send + 'static> = Never;
149
150 fn new_reference_notifier<T: Send + 'static>(
151 debug_references: DynDebugReferences,
152 ) -> (Self::ReferenceNotifier<T>, Self::ReferenceReceiver<T>) {
153 panic!(
157 "FakeBindingsCtx can't create deferred reference notifiers for type {}: \
158 debug_references={debug_references:?}",
159 core::any::type_name::<T>()
160 );
161 }
162}
163
164impl<Id, Event: Debug, State, FrameMeta> DeferredResourceRemovalContext
165 for FakeBindingsCtx<Id, Event, State, FrameMeta>
166{
167 fn defer_removal<T: Send + 'static>(&mut self, receiver: Self::ReferenceReceiver<T>) {
168 match receiver {}
169 }
170}
171
172impl<TimerId, Event: Debug, State, FrameMeta> WithFakeTimerContext<TimerId>
173 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
174{
175 fn with_fake_timer_ctx<O, F: FnOnce(&FakeTimerCtx<TimerId>) -> O>(&self, f: F) -> O {
176 f(&self.timers)
177 }
178
179 fn with_fake_timer_ctx_mut<O, F: FnOnce(&mut FakeTimerCtx<TimerId>) -> O>(
180 &mut self,
181 f: F,
182 ) -> O {
183 f(&mut self.timers)
184 }
185}
186
187impl<TimerId, Event: Debug, State, FrameMeta> AlwaysDefaultsSettingsContext
188 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
189{
190}
191
192impl<TimerId: Debug, Event: Debug, State, FrameMeta> MatcherBindingsTypes
193 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
194{
195 type DeviceClass = ();
196}