spire_enum 1.0.0

Procedural macros to facilitate enum usage, such as when delegating implementations, extracting variant types, or creating enum tables.
Documentation
/// Plug-and-Play extension methods for enums created by [`spire_enum_macros`].
///
/// There is no need to manually implement any of this trait's methods,
/// if you want to make them available for your enum all you have to do is
/// make sure the setting `impl_conversions` is active when using the macro [`delegated_enum`](crate::prelude::delegated_enum).
pub trait EnumExtensions: Sized {
    /// Attempts to "cast" this enum into one of its variants.
    ///
    /// # Returns
    /// - `Ok(Var)`, if `self` matches the variant `Var`.
    /// - `Err(Self)`, otherwise.
    ///
    /// The error type allows you to keep the enum value in case it does not match the variant `Var`.
    ///
    /// # Example
    /// ```rust ignore
    /// use spire_enum::prelude::EnumExtensions;
    ///
    /// #[derive(Debug, PartialEq)]
    /// enum Setting {
    ///     TextSpeed(f64),
    ///     Volume(i32),
    /// }
    ///
    /// let setting = Setting::TextSpeed(5.0);
    /// assert_eq!(setting.try_into_var::<f64>(), Ok(5.0));
    ///
    /// let setting = Setting::TextSpeed(5.0);
    /// assert!(setting.try_into_var::<i32>().is_err());
    /// ```
    #[inline]
    fn try_into_var<Var>(self) -> Result<Var, Self>
    where Var: FromEnum<Self> {
        Var::from_enum(self)
    }

    /// Attempts to get a reference to the variant `Var`, if `self` matches the variant.
    ///
    /// # Example
    /// ```rust ignore
    /// use spire_enum::prelude::EnumExtensions;
    ///
    /// #[derive(Debug, PartialEq)]
    /// enum Setting {
    ///     TextSpeed(f64),
    ///     Volume(i32),
    /// }
    ///
    /// let setting = Setting::TextSpeed(5.0);
    /// assert_eq!(setting.try_ref_var::<f64>(), Some(&5.0));
    /// assert!(setting.try_ref_var::<i32>().is_none());
    /// ```
    #[inline]
    fn try_ref_var<Var>(&self) -> Option<&Var>
    where Var: FromEnumRef<Self> {
        Var::from_enum_ref(self)
    }

    /// Attempts to get a mutable reference to the variant `Var`, if `self` matches the variant.
    ///
    /// # Example
    /// ```rust ignore
    /// use spire_enum::prelude::EnumExtensions;
    ///
    /// #[derive(Debug, PartialEq)]
    /// enum Setting {
    ///     TextSpeed(f64),
    ///     Volume(i32),
    /// }
    ///
    /// let setting = Setting::TextSpeed(5.0);
    /// assert_eq!(setting.try_mut_var::<f64>(), Some(&mut 5.0));
    /// assert!(setting.try_mut_var::<i32>().is_none());
    /// ```
    #[inline]
    fn try_mut_var<Var>(&mut self) -> Option<&mut Var>
    where Var: FromEnumMut<Self> {
        Var::from_enum_mut(self)
    }

    /// Checks if `self` matches the variant `Var`.
    ///
    /// # Example
    /// ```rust ignore
    /// use spire_enum::prelude::EnumExtensions;
    ///
    /// #[derive(Debug, PartialEq)]
    /// enum Setting {
    ///     TextSpeed(f64),
    ///     Volume(i32),
    /// }
    ///
    /// let setting = Setting::TextSpeed(5.0);
    /// assert!(setting.is_var::<f64>());
    /// assert!(!setting.is::<i32>());
    /// ```
    #[inline]
    fn is_var<Var>(&self) -> bool
    where Var: FromEnumRef<Self> {
        self.try_ref_var::<Var>().is_some()
    }
}

pub trait FromEnum<Enum>: Sized {
    /// The inverse of [`EnumExtensions::try_into_var`], see that method's documentation for more.
    ///
    /// Implementations of this method are (usually) generated by the macro [`delegated_enum`](crate::prelude::delegated_enum).
    fn from_enum(e: Enum) -> Result<Self, Enum>;
}

pub trait FromEnumRef<Enum> {
    /// The inverse of [`EnumExtensions::try_ref_var`], see that method's documentation for more.
    ///
    /// Implementations of this method are (usually) generated by the macro [`delegated_enum`](crate::prelude::delegated_enum).
    fn from_enum_ref(e: &Enum) -> Option<&Self>;
}

pub trait FromEnumMut<Enum> {
    /// The inverse of [`EnumExtensions::try_mut_var`], see that method's documentation for more.
    ///
    /// Implementations of this method are (usually) generated by the macro [`delegated_enum`](crate::prelude::delegated_enum).
    fn from_enum_mut(e: &mut Enum) -> Option<&mut Self>;
}