#enum #derive #unknown #testing #pub #debugging #variant #error #impl #quick-error

wrapped_enum

Useful macro to wrap existing types in an enum (common use for quick error handling)

2 releases

Uses old Rust 2015

0.1.3 Jul 8, 2015
0.1.2 Jul 8, 2015
0.1.1 Jul 8, 2015
0.1.0 Jul 8, 2015

#2435 in Rust patterns

25 downloads per month
Used in tabin-plugins

MIT license

4KB
78 lines

//! wrapped_enum! - Wrap multiple types into an Enum //! //! This is useful when returning multiple types. //! simply to just work on an enum of known types. //! //! Documentation is required when using public enums //! //! //! # #[macro_use] extern crate wrapped_enum; //! # use std::io; //! #[derive(Debug)] //! pub enum TestError { //! ErrorA, //! ErrorB(u8, u16), //! ErrorC(String), //! } //! //! wrapped_enum!{ //! #[derive(Debug)] //! /// Document your pub enums //! pub enum DocumentedEnum { //! /// Variants too //! Io(io::Error), //! /// Documentation is required for pub enums //! Test(TestError), //! /// Unknown error //! Unknown(()), //! } //! } //! //! wrapped_enum!{ //! #[derive(Debug, Eq, PartialEq)] //! /// You can't document private variants //! enum UndocumentedEnum { //! // However, there is nothing wrong with normal comments //! Byte(u8), // 00-FF //! DoubleByte(u16), // 0000-FFFF //! } //! } //! //! # fn main() { //! assert!(UndocumentedEnum::from(0u8) == UndocumentedEnum::Byte(0)); //! assert!(UndocumentedEnum::from(0u16) == UndocumentedEnum::DoubleByte(0)); //! # } //!

#[macro_export] macro_rules! wrapped_enum { ($(#[$attr:meta])* pub enum $enum_name:ident { $($(#[$variant_attr:meta])+ $enum_variant_name:ident($ty:ty)),+ $(,)* } ) => ( $(#[$attr])* pub enum $enum_name { $($(#[$variant_attr])+ $enum_variant_name($ty)),+ } $(impl From<$ty> for $enum_name { fn from (ty: $ty) -> Self { $enum_name::$enum_variant_name(ty) } })+ ); ($(#[$attr:meta])* enum $enum_name:ident { $($enum_variant_name:ident($ty:ty)),+ $(,)* } ) => ( $(#[$attr])* enum $enum_name { $($enum_variant_name($ty)),+ } $(impl From<$ty> for $enum_name { fn from (ty: $ty) -> Self { $enum_name::$enum_variant_name(ty) } })+ ); }

#[cfg(test)] mod test { #[derive(Debug)] #[allow(dead_code)] pub enum CommunicationError { HumanError(Human, ErrorAction), UnknownError, }

#[derive(Debug)]
#[allow(dead_code)]
pub enum ErrorAction {
    AttemptedToStealSecrets,
    StoleSecrets,
}

#[derive(Debug)]
#[allow(dead_code)]
pub enum Human {
    Alice, // Good
    Bob,   // Good
    Carol, // Good
    Dave,  // Good
    Eve,   // Bad
}

wrapped_enum!{
    #[derive(Debug)]
    /// Document your pub enums
    pub enum TestError {

// /// Variants too // Io(io::Error), /// Documentation is required for pub enums Test(CommunicationError), /// Unknown error Unknown(()), } }

wrapped_enum!{
    #[derive(Debug)]
    /// You can't document private variants
    enum UndocumentedEnum {
        // However, there is nothing wrong with normal comments
        Byte(u8),        // 00-FF
        DoubleByte(u16), // 0000-FFFF
    }
}

#[test]
fn eve_intercept_alice_and_bobs_communication() {
    let error: Result<(), CommunicationError> =
        Err(CommunicationError::HumanError(Human::Eve,
                                           ErrorAction::AttemptedToStealSecrets));

    let result: Result<(), TestError> = error.map_err(From::from);

    assert!(result.is_err());
}

}

No runtime deps