avid 0.6.1

A plug-and-play scripting language
Documentation
macro_rules! enum_type {
    (
        $(#[doc = $outerdoc:expr])*
        hidden $name:ident {
            $(
                $(#[doc = $doc:expr])*
                $subtype:ident$(($typ:ty))?
            ),*
        }
    ) => {
        use paste::paste;
        #[allow(clippy::derive_partial_eq_without_eq)]
        #[allow(unused)]
        #[derive(Debug, PartialEq)]
        $(#[doc = $outerdoc])*
        pub(crate) enum $name {
            $(
                $(#[doc = $doc])*
                $subtype$(
                    ($typ)
                )?
            ),*
        }
        paste! {
            impl $name {
                #[allow(unused)]
                #[doc = "Gets the type of self and converts it into [" $name "Type]"]
                pub(crate) fn get_type(&self) -> [<$name Type>] {
                    match self {
                        $(
                            Self::$subtype$(([<_ $typ:lower _val>]))? => [<$name Type>]::$subtype
                        ),*
                    }
                }
                $(
                    $(
                    #[allow(unused)]
                    #[doc = "If self is [" $name "::" $subtype "], unwraps that and returns the value. If not, it panics."]
                    pub(crate) fn [<unwrap_ $subtype:lower>](self) -> $typ {
                        match self {
                            Self::$subtype(v) => v,
                            _ => panic!(stringify!(Could not unwrap $subtype!))
                        }
                    }
                    )?
                )*
            }
            #[allow(clippy::derive_partial_eq_without_eq)]
            #[derive(Debug, PartialEq, Copy, Clone)]
            #[allow(unused)]
            #[doc = "The possible types of [" $name "]"]
            pub(crate) enum [<$name Type>] {

                $(
                    #[doc = "Represents [" $name "::" $subtype "]."]
                    $subtype,
                )*
            }

            #[allow(unused)]
            #[doc = "All of the possible values of ["$name "Type]."]
            pub(crate) const [<$name:upper _TYPES>]: [[<$name Type>]; [$([<$name Type>]::$subtype),*].len()] = [$([<$name Type>]::$subtype),*];
        }
    };
    (
        $(#[doc = $outerdoc:expr])*
        $name:ident {
            $(
                $(#[doc = $doc:expr])*
                $subtype:ident$(($typ:ty))?
            ),*
        }
    ) => {
        use paste::paste;
        #[allow(clippy::derive_partial_eq_without_eq)]
        #[allow(unused)]
        #[derive(Debug, PartialEq)]
        $(#[doc = $outerdoc])*
        pub enum $name {
            $(
                $(#[doc = $doc])*
                $subtype$(
                    ($typ)
                )?
            ),*
        }
        paste! {
            impl $name {
                #[allow(unused)]
                #[doc = "Gets the type of self and converts it into [" $name "Type]"]
                pub fn get_type(&self) -> [<$name Type>] {
                    match self {
                        $(
                            Self::$subtype$(([<_ $typ:lower _val>]))? => [<$name Type>]::$subtype
                        ),*
                    }
                }
                $(
                    $(
                    #[allow(unused)]
                    #[doc = "If self is [" $name "::" $subtype "], unwraps that and returns the value. If not, it panics."]
                    pub fn [<unwrap_ $subtype:lower>](self) -> $typ {
                        match self {
                            Self::$subtype(v) => v,
                            _ => panic!(stringify!(Could not unwrap $subtype!))
                        }
                    }
                    )?
                )*
            }
            #[allow(clippy::derive_partial_eq_without_eq)]
            #[derive(Debug, PartialEq, Copy, Clone)]
            #[allow(unused)]
            #[doc = "The possible types of [" $name "]"]
            pub enum [<$name Type>] {

                $(
                    #[doc = "Represents [" $name "::" $subtype "]."]
                    $subtype,
                )*
            }

            #[allow(unused)]
            #[doc = stringify!(All of the possible values of [<$name Type>].)]
            pub const [<$name:upper _TYPES>]: [[<$name Type>]; [$([<$name Type>]::$subtype),*].len()] = [$([<$name Type>]::$subtype),*];
        }
    };
}

// Code taken from here: https://github.com/rust-lang/rfcs/issues/2790#issue-509292593
macro_rules! static_assert {
    ($condition:expr) => {
        #[deny(const_err)]
        const _: &() = &[()][1 - if $condition { 1 } else { 0 }];
    };
    ($condition:expr, $msg:expr) => {
        #[deny(const_err)]
        const _: (&(), &str) = (&[()][1 - if $condition { 1 } else { 0 }], $msg);
    };
}

macro_rules! static_assert_eq {
    ($lhs:expr, $rhs:expr) => {
        static_assert!($lhs == $rhs)
    };
    ($lhs:expr, $rhs:expr, $msg:expr) => {
        static_assert!($lhs == $rhs, $msg)
    };
}

pub(crate) const fn is_send<T: Send>() {}
macro_rules! assert_send {
    ($typ:ty) => {
        #[allow(unused)]
        const _: () = crate::macros::is_send::<$typ>();
    };
}