Macro declarative_type_state::delegated_enum

source ·
macro_rules! delegated_enum {
    (
	    ENUM_OUT: {
		    $( #[$enum_meta: meta] )*
		    $enum_vis: vis enum $enum_ident: ident
		    $( <[ $( $enum_gen: tt )* ]> )?
			$( where [ $( $enum_bound: tt )* ] )?
		    {
			    $( $var_ident: ident ($var_ty: ty) ),*
			    $(,)?
		    }
	    }
	    
	    DELEGATES: {
		    $(
		        impl $( <[ $( $trait_gen: tt )*  ]> )? 
		        trait $trait_ty: path
		        $( where [ $( $trait_bound: tt )* ] )?
		        {
				    $( [ $( $item: tt )* ] )*
			    }
		    )*
		    
		    $(
			    impl {
			        $( [ $( $std_impl: tt )* ] )*
			    }
		    )?
	    }
    ) => { ... };
}
Expand description

Generates an enum with the specified variants, and implements the specified traits and methods for the enum, where each variant’s type also implements the traits/methods.

§Also implements for each variant’s type:

  • From for Enum
  • TryFrom for Variant

§Input

  • ENUM_OUT: Defines the output enum with its metadata, visibility, name, generics, and variants.
  • DELEGATES: Specifies the traits and methods to be implemented for the enum. All variants of the enum must implement the traits/methods.

§ENUM_OUT:

[enum_meta]
[visibility] enum [name]<[generics]> [where [bounds]] {
    [var_name_A]([var_type_A]),
    [var_name_B]([var_type_B]),
}
 
  • [enum_meta]: Metadata attributes to be applied to the enum. (e.g., #[derive(Debug, Clone)])
  • [visibility]: Visibility level of the enum. (e.g., pub)
  • [name]: Identifier (name) of the enum. (e.g., MyEnum)
  • [generics]: Optional generics for the enum, must be placed inside brackets. (e.g., <[T]>)
  • where [bounds]: Optional where clause for the enum, must be placed inside brackets. (e.g., where [T: SomeTrait])
  • var_name: Variants of the enum along with their types. (e.g., VariantOne(TypeOne), VariantTwo(TypeTwo))

§DELEGATES - Traits:

Specifies the traits to be implemented for the enum. All variants of the enum must implement the traits.

All items inside the trait must be placed inside brackets.

impl<[generics]> trait [trait_type] [where [bounds]] {
    [ type [associated_type_name] = [associated_type] ]
    [ const [associated_const_name]: [const_type] = [expr] ]
 
    [ fn [method_name]<[generics]>([self_type], [args]) -> [return_type] ]
}
  • [generics]: Optional generics for the trait implementation. Must be placed inside brackets.
  • [trait_type]: The path of the trait to be implemented.
  • where [bounds]: Optional where clause for the trait implementation. Bounds must be placed inside brackets.
  • Methods:
    • [method_name]: Method name.
    • <[generics]>: Optional generics for the method. Must be placed inside brackets.
    • ([self_type], [args]): Method parameters including self-reference.
    • -> [return_type]: Return type of the method (optional if return type is ()).
  • Associated types:
    • [associated_type_name]: Name of an associated type.
    • = [associated_type]: Type associated with the name.
  • Associated constants:
    • [associated_const_name]: Name of an associated constant.
    • : [const_type]: Type of the associated constant.
    • = [expr]: Value of the associated constant.

§DELEGATES - Methods:

Additional method implementations. All variants of the enum must have methods with the same name and number of arguments.

impl {
    [fn [method_name]<[generics]>([self_type], [args]) -> [return_type]]
}
  • [method_name]: Method name.
  • <[generics]>: Optional generics for the method. Must be placed inside brackets.
  • ([self_type], [args]): Method parameters including self-reference.
  • -> [return_type]: Return type of the method (optional if return type is ()).

§Example

use declarative_type_state::delegated_enum;
use std::fmt::{Debug, Formatter};

delegated_enum! {
    ENUM_OUT: {
        enum IDebug {
            Int(i32),
            Bool(bool),
            String(String),
        }
    }

    DELEGATES: {
        impl trait Debug {
            [fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error>]
        }
 
        impl {
            [fn to_string(&self) -> String]
        }
    }
}

let debug = IDebug::Int(5);
assert_eq!(format!("{debug:?}"), format!("{:?}", 5_i32));
assert_eq!(debug.to_string(), 5.to_string());