1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Utilities which allow code to be more robust to changes in dependencies.
//!
//! The utilities in this crate allow code to depend on details of its
//! dependencies which would not normally be captured by code using the
//! canonical Rust style. See [this document][rust-patterns] for a discussion of
//! when and why this might be desirable.
//!
//! [rust-patterns]: https://fuchsia.dev/fuchsia-src/contribute/contributing-to-netstack/rust-patterns
#![no_std]
#![deny(missing_docs)]
use core::{convert::Infallible as Never, task::Poll};
/// An extension trait adding functionality to [`Result`].
pub trait ResultExt<T, E> {
/// Like [`Result::ok`], but the caller must provide the error type being
/// discarded.
///
/// This allows code to be written which will stop compiling if a result's
/// error type changes in the future.
fn ok_checked<EE: sealed::EqType<E>>(self) -> Option<T>;
}
impl<T, E> ResultExt<T, E> for Result<T, E> {
fn ok_checked<EE: sealed::EqType<E>>(self) -> Option<T> {
Result::ok(self)
}
}
/// An extension trait adding functionality to [`Poll`].
pub trait PollExt<T> {
/// Like [`Poll::is_ready`], but the caller must provide the inner type.
///
/// This allows both the authors and the reviewers to check if information
/// is being discarded unnoticed.
fn is_ready_checked<TT: sealed::EqType<T>>(&self) -> bool;
}
impl<T> PollExt<T> for Poll<T> {
fn is_ready_checked<TT: sealed::EqType<T>>(&self) -> bool {
Poll::is_ready(self)
}
}
/// A trait providing unreachability assertion enforced by the type system.
///
/// # Example
/// ```
/// use core::convert::Infallible as Never;
///
/// /// Provides guaranteed winning lottery numbers.
/// trait LotteryOracle {
/// fn get_winning_number(&self) -> u32;
/// }
///
/// // Might return a thing that gives winning lottery numbers.
/// fn try_get_lottery_oracle() -> Option<impl LotteryOracle> {
/// // This function always returns `None` but we still need a type that
/// // the option _could_ hold.
///
/// /// Uninstantiable type that implements [`LotteryOracle`].
/// struct UninstantiableOracle(Never);
///
/// /// Enable use with [`UnreachableExt`].
/// impl AsRef<Never> for UninstantiableOracle {
/// fn as_ref(&self) -> Never {
/// &self.0
/// }
/// }
///
/// /// Trivial implementation that can't actually be used.
/// impl LotteryOracle for UninstantiableOracle {
/// fn get_winning_number(&self) -> u32 {
/// self.uninstantiable_unreachable()
/// }
/// }
///
/// Option::<UninstantiableOracle>::None
/// }
/// ```
///
/// # Implementing
///
/// This trait is blanket-implemented for any type that can be used to construct
/// an instance of [`Never`]. To use it, simply implement [`AsRef<Never>`].
pub trait UnreachableExt: sealed::Sealed {
/// A method that can't be called.
///
/// This method returns an instance of any caller-specified type, which
/// makes it impossible to implement unless the method receiver is itself
/// uninstantiable. This method is similar to the `unreachable!` macro, but
/// should be preferred over the macro since it uses the type system to
/// enforce unreachability where `unreachable!` indicates a logical
/// assertion checked at runtime.
fn uninstantiable_unreachable<T>(&self) -> T;
}
impl<N: AsRef<Never>> UnreachableExt for N {
fn uninstantiable_unreachable<T>(&self) -> T {
match *self.as_ref() {}
}
}
mod sealed {
use core::convert::Infallible as Never;
/// `EqType<T>` indicates that the implementer is equal to `T`.
///
/// For all `T`, `T: EqType<T>`. For all distinct `T` and `U`, `T:
/// !EqType<U>`.
pub trait EqType<T> {}
impl<T> EqType<T> for T {}
/// Trait that can only be implemented within this crate.
pub trait Sealed {}
impl<T: AsRef<Never>> Sealed for T {}
}