#![warn(missing_docs)]
#![warn(missing_copy_implementations, missing_debug_implementations)]
#![warn(unused_qualifications, unused_results)]
#![warn(future_incompatible)]
#![warn(unused)]
#![forbid(broken_intra_doc_links)]
pub use vesta_macro::{case, Match};
#[doc(hidden)]
pub mod vesta {
pub use super::*;
}
pub unsafe trait Match: Sized {
type Range: sealed::Range;
fn tag(&self) -> Option<usize>;
}
pub trait CaseExt: Sized {
#[inline(always)]
unsafe fn case<const N: usize>(self) -> Self::Case
where
Self: Case<N>,
{
Case::case(self)
}
#[inline(always)]
fn try_case<const N: usize>(self) -> Result<Self::Case, Self>
where
Self: Case<N>,
{
Case::try_case(self)
}
#[inline(always)]
fn uncase<T, const N: usize>(self) -> T
where
T: Case<N, Case = Self>,
{
Case::uncase(self)
}
}
impl<T: Sized> CaseExt for T {}
#[inline(always)]
pub fn assert_exhaustive<T, const N: usize>(_: &T)
where
T: Match<Range = Exhaustive<N>>,
{
}
#[doc(hidden)]
#[inline(always)]
pub unsafe fn unreachable<T>() -> T {
#[cfg(release)]
{
core::hint::unreachable_unchecked()
}
#[cfg(not(release))]
{
core::unreachable!("invariant violation in `vesta::Match` or `vesta::Case` implementation")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Exhaustive<const N: usize> {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Nonexhaustive {}
pub trait Case<const N: usize>: Match {
type Case;
unsafe fn case(this: Self) -> Self::Case;
fn try_case(this: Self) -> Result<Self::Case, Self> {
if this.tag() == Some(N) {
Ok(unsafe { Case::case(this) })
} else {
Err(this)
}
}
fn uncase(case: Self::Case) -> Self;
}
mod sealed {
pub trait Range {}
impl<const N: usize> Range for super::Exhaustive<N> {}
impl Range for super::Nonexhaustive {}
}
mod impls;