macro_rules! assert_enum_variants {
($enum:path, { $($variant:ident),* $(,)? }) => { ... };
}Expand description
This macro performs a compile-time check to validate that all variants of an enum are as provided in the macro invocation.
§Example
use assert_enum_variants::assert_enum_variants;
#[allow(dead_code)]
pub enum MyEnum {
A,
B(u32),
C {
a: String,
b: u32,
},
}
// This will compile successfully
// because all variants of `MyEnum` are accounted for.
assert_enum_variants!(MyEnum, { A, B, C });It will fail to compile if any of the variants are missing or if there are any extra variants.
§Example of faliure due to missing variants
ⓘ
use assert_enum_variants::assert_enum_variants;
#[allow(dead_code)]
pub enum MyEnum {
A,
B(u32),
C {
a: String,
b: u32,
},
}
// This will fail to compile
// because the `C` variant is missing.
assert_enum_variants!(MyEnum, { A, B });§Example of failure due to extra variants
ⓘ
use assert_enum_variants::assert_enum_variants;
#[allow(dead_code)]
pub enum MyEnum {
A,
B(u32),
C {
a: String,
b: u32,
},
}
// This will fail to compile
// because the `D` variant is not present on `MyEnum`.
assert_enum_variants!(MyEnum, { A, B, C, D });§Reasons for using this macro
Let’s say you’re writing some code that needs to handle all variants of an enum but there could be a situation that none of the variants fits.
enum ResumeFileFormat {
Pdf,
Docx,
Doc,
}
// ...
impl ResumeFileFormat {
fn from_extension(ext: &str) -> Option<Self> {
use ResumeFileFormat::{Pdf, Docx, Doc};
let file_format: ResumeFileFormat = match ext {
"pdf" => Pdf,
"docx" => Docx,
"doc" => Doc,
_ => return None,
};
Some(file_format)
}
}Notice that due to a wildcard pattern, the compiler will not warn you if you
add a new variant to the enum and forget to modify the from_extension.
That is, unless you use the assert_enum_variants! macro.
The following code will fail to compile if you add a new variant to the enum
and forget to modify the from_extension function.
ⓘ
use assert_enum_variants::assert_enum_variants;
enum ResumeFileFormat {
Pdf,
Docx,
Doc,
Json,
}
// ...
impl ResumeFileFormat {
fn from_extension(ext: &str) -> Option<Self> {
use ResumeFileFormat::{Pdf, Docx, Doc};
// This will fail to compile because the `Json` variant is missing.
assert_enum_variants!(ResumeFileFormat, { Pdf, Docx, Doc });
let file_format: ResumeFileFormat = match ext {
"pdf" => Pdf,
"docx" => Docx,
"doc" => Doc,
_ => return None,
};
Some(file_format)
}
}