netstack3_base/testutil/
fake_core.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Shareable core context fakes.
6
7use alloc::vec::Vec;
8use core::marker::PhantomData;
9
10use derivative::Derivative;
11use packet::{BufferMut, Serializer};
12
13use crate::testutil::{FakeFrameCtx, FakeTxMetadata, WithFakeFrameContext};
14use crate::{
15    ContextProvider, CoreTxMetadataContext, CounterContext, ResourceCounterContext, SendFrameError,
16    SendableFrameMeta, TxMetadataBindingsTypes,
17};
18
19/// A test helper used to provide an implementation of a core context.
20#[derive(Derivative)]
21#[derivative(Default(bound = "S: Default"))]
22pub struct FakeCoreCtx<S, Meta, DeviceId> {
23    /// Generic state kept in this fake context.
24    pub state: S,
25    /// A fake frame context for outgoing frames.
26    pub frames: FakeFrameCtx<Meta>,
27    _devices_marker: PhantomData<DeviceId>,
28}
29
30impl<S, Meta, DeviceId> ContextProvider for FakeCoreCtx<S, Meta, DeviceId> {
31    type Context = Self;
32
33    fn context(&mut self) -> &mut Self::Context {
34        self
35    }
36}
37
38impl<C, S, Meta, DeviceId> CounterContext<C> for FakeCoreCtx<S, Meta, DeviceId>
39where
40    S: CounterContext<C>,
41{
42    fn counters(&self) -> &C {
43        CounterContext::<C>::counters(&self.state)
44    }
45}
46
47impl<C, S, R, Meta, DeviceId> ResourceCounterContext<R, C> for FakeCoreCtx<S, Meta, DeviceId>
48where
49    S: ResourceCounterContext<R, C>,
50{
51    fn per_resource_counters<'a>(&'a self, resource: &'a R) -> &'a C {
52        ResourceCounterContext::<R, C>::per_resource_counters(&self.state, resource)
53    }
54}
55
56impl<BC, S, Meta, DeviceId> SendableFrameMeta<FakeCoreCtx<S, Meta, DeviceId>, BC> for Meta {
57    fn send_meta<SS>(
58        self,
59        core_ctx: &mut FakeCoreCtx<S, Meta, DeviceId>,
60        bindings_ctx: &mut BC,
61        frame: SS,
62    ) -> Result<(), SendFrameError<SS>>
63    where
64        SS: Serializer,
65        SS::Buffer: BufferMut,
66    {
67        self.send_meta(&mut core_ctx.frames, bindings_ctx, frame)
68    }
69}
70
71impl<S, Meta, DeviceId> FakeCoreCtx<S, Meta, DeviceId> {
72    /// Constructs a `FakeCoreCtx` with the given state and default
73    /// `FakeTimerCtx`, and `FakeFrameCtx`.
74    pub fn with_state(state: S) -> Self {
75        FakeCoreCtx { state, frames: FakeFrameCtx::default(), _devices_marker: PhantomData }
76    }
77
78    /// Get the list of frames sent so far.
79    pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
80        self.frames.frames()
81    }
82
83    /// Take the list of frames sent so far.
84    pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
85        self.frames.take_frames()
86    }
87
88    /// Consumes the `FakeCoreCtx` and returns the inner state.
89    pub fn into_state(self) -> S {
90        self.state
91    }
92}
93
94impl<S, Meta, DeviceId> WithFakeFrameContext<Meta> for FakeCoreCtx<S, Meta, DeviceId> {
95    fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<Meta>) -> O>(&mut self, f: F) -> O {
96        f(&mut self.frames)
97    }
98}
99
100impl<T, S, Meta, DeviceId, BT> CoreTxMetadataContext<T, BT> for FakeCoreCtx<S, Meta, DeviceId>
101where
102    BT: TxMetadataBindingsTypes<TxMetadata = FakeTxMetadata>,
103{
104    fn convert_tx_meta(&self, _tx_meta: T) -> FakeTxMetadata {
105        FakeTxMetadata
106    }
107}
108
109impl<S, Meta, DeviceId> AsRef<S> for FakeCoreCtx<S, Meta, DeviceId> {
110    fn as_ref(&self) -> &S {
111        &self.state
112    }
113}