netstack3_base/
uninstantiable.rs

1// Copyright 2022 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//! A collection of uninstantiable types.
6//!
7//! These uninstantiable types can be used to satisfy trait bounds in
8//! uninstantiable situations. Different parts of core provide implementations
9//! of their local traits on these types, so they can be used in uninstantiable
10//! contexts.
11
12use core::convert::Infallible as Never;
13use core::marker::PhantomData;
14
15use explicit::UnreachableExt as _;
16
17use crate::{
18    BidirectionalConverter, CoreTimerContext, CoreTxMetadataContext, CounterContext, Device,
19    DeviceIdContext, ResourceCounterContext, TimerBindingsTypes, TxMetadataBindingsTypes,
20};
21
22/// An uninstantiable type.
23#[derive(Clone, Copy)]
24pub struct Uninstantiable(Never);
25
26impl AsRef<Never> for Uninstantiable {
27    fn as_ref(&self) -> &Never {
28        &self.0
29    }
30}
31
32impl<I, O> BidirectionalConverter<I, O> for Uninstantiable {
33    fn convert_back(&self, _: O) -> I {
34        self.uninstantiable_unreachable()
35    }
36    fn convert(&self, _: I) -> O {
37        self.uninstantiable_unreachable()
38    }
39}
40
41/// An uninstantiable type that wraps an instantiable type, `A`.
42///
43/// This type can be used to more easily implement traits where `A` already
44/// implements the trait.
45// TODO(https://github.com/rust-lang/rust/issues/118212): Simplify the trait
46// implementations once Rust supports function delegation. Those impls are
47// spread among the core crates.
48pub struct UninstantiableWrapper<A>(Never, PhantomData<A>);
49
50impl<A> AsRef<Never> for UninstantiableWrapper<A> {
51    fn as_ref(&self) -> &Never {
52        let Self(never, _marker) = self;
53        &never
54    }
55}
56
57impl<T, BT, C> CoreTimerContext<T, BT> for UninstantiableWrapper<C>
58where
59    BT: TimerBindingsTypes,
60    C: CoreTimerContext<T, BT>,
61{
62    fn convert_timer(dispatch_id: T) -> BT::DispatchId {
63        C::convert_timer(dispatch_id)
64    }
65}
66
67impl<P, C> CounterContext<C> for UninstantiableWrapper<P> {
68    fn counters(&self) -> &C {
69        self.uninstantiable_unreachable()
70    }
71}
72
73impl<P, R, C> ResourceCounterContext<R, C> for UninstantiableWrapper<P> {
74    fn per_resource_counters(&self, _resource: &R) -> &C {
75        self.uninstantiable_unreachable()
76    }
77}
78
79impl<T, BT, C> CoreTxMetadataContext<T, BT> for UninstantiableWrapper<C>
80where
81    BT: TxMetadataBindingsTypes,
82{
83    fn convert_tx_meta(&self, _tx_meta: T) -> BT::TxMetadata {
84        self.uninstantiable_unreachable()
85    }
86}
87
88impl<D: Device, C: DeviceIdContext<D>> DeviceIdContext<D> for UninstantiableWrapper<C> {
89    type DeviceId = C::DeviceId;
90    type WeakDeviceId = C::WeakDeviceId;
91}
92
93impl<A: Iterator> Iterator for UninstantiableWrapper<A> {
94    type Item = A::Item;
95
96    fn next(&mut self) -> Option<Self::Item> {
97        self.uninstantiable_unreachable()
98    }
99}