netstack3_base/
map_deref.rs

1// Copyright 2025 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//! Utilities for mapping deref guards like mutex or RCU guards.
6
7use core::marker::PhantomData;
8use core::ops::Deref;
9
10/// A helper type that provides mapping `Deref` implementations.
11pub struct MapDeref<S, T, F> {
12    storage: S,
13    map: F,
14    _marker: PhantomData<T>,
15}
16
17impl<S, T, F> MapDeref<S, T, F> {
18    /// Retrieves the inner storage, undoing any mapping.
19    pub fn into_inner(self) -> S {
20        self.storage
21    }
22}
23
24impl<S, T, F> Deref for MapDeref<S, T, F>
25where
26    S: Deref,
27    F: Fn(&S::Target) -> &T,
28{
29    type Target = T;
30
31    fn deref(&self) -> &Self::Target {
32        let Self { storage, map, _marker } = self;
33        map(&*storage)
34    }
35}
36
37/// A trait providing an easy way to instantiate [`MapDeref`].
38pub trait MapDerefExt: Deref + Sized {
39    /// Maps this value from the current `Deref::Target` to `T`.
40    fn map_deref<F: Fn(&Self::Target) -> &T, T>(self, f: F) -> MapDeref<Self, T, F>;
41}
42
43impl<S> MapDerefExt for S
44where
45    S: Deref + Sized,
46{
47    fn map_deref<F: Fn(&Self::Target) -> &T, T>(self, map: F) -> MapDeref<Self, T, F> {
48        MapDeref { storage: self, map, _marker: PhantomData::<T>::default() }
49    }
50}