fayalite 0.2.0

Hardware Description Language embedded in Rust, using FIRRTL's semantics
Documentation
// SPDX-License-Identifier: LGPL-3.0-or-later
// See Notices.txt for copyright information
use std::{fmt::Debug, hash::Hash, mem::ManuallyDrop, ptr};

mod sealed {
    pub trait Sealed {}
}

/// # Safety
/// the only implementation is `ConstBool<Self::VALUE>`
pub unsafe trait GenericConstBool:
    sealed::Sealed + Copy + Ord + Hash + Default + Debug + 'static + Send + Sync
{
    const VALUE: bool;
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct ConstBool<const VALUE: bool>;

impl<const VALUE: bool> Debug for ConstBool<VALUE> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_tuple("ConstBool").field(&Self::VALUE).finish()
    }
}

impl<const VALUE: bool> sealed::Sealed for ConstBool<VALUE> {}

/// SAFETY: the only implementation is `ConstBool<Self::VALUE>`
unsafe impl<const VALUE: bool> GenericConstBool for ConstBool<VALUE> {
    const VALUE: bool = VALUE;
}

pub trait ConstBoolDispatchTag {
    type Type<Select: GenericConstBool>;
}

pub enum ConstBoolDispatch<FalseT, TrueT> {
    False(FalseT),
    True(TrueT),
}

impl<FalseT, TrueT> ConstBoolDispatch<FalseT, TrueT> {
    pub fn new<
        Tag: ConstBoolDispatchTag<Type<ConstBool<false>> = FalseT>
            + ConstBoolDispatchTag<Type<ConstBool<true>> = TrueT>,
        Select: GenericConstBool,
    >(
        v: Tag::Type<Select>,
    ) -> Self {
        let v = ManuallyDrop::new(v);
        let v_ptr: *const Tag::Type<Select> = &*v;
        // SAFETY: reads the exact same type, since Select is really ConstBool<Select::VALUE>
        unsafe {
            if Select::VALUE {
                ConstBoolDispatch::True(ptr::read(v_ptr.cast()))
            } else {
                ConstBoolDispatch::False(ptr::read(v_ptr.cast()))
            }
        }
    }
}