It'll be more efficient to do the string matching with a regular expression than iterating over each variant name and trying to find it as a substring in the target strings. I put together an example of how this can be done using the strum
and regex
crates.
The enum with a long list of variants, and a set of target strings to search.
use std::str::FromStr;
use lazy_static::lazy_static;
use regex::Regex;
use strum::{EnumString, EnumVariantNames, VariantNames};
#[derive(EnumString, EnumVariantNames, Debug)]
enum Thing {
Foo,
Bar,
Baz,
Qux,
Quux,
Quuz,
Corge,
Grault,
Garply,
Waldo,
Fred,
Plugh,
Xyzzy,
Thud,
}
// Target strings to look for variant names in.
//
static STRINGS: [&str; 10] = [
"fdskQuuzjfkds", "fkjdFoo", "Fred", "fkdXyzzy", "Plughfkdjs",
"QuuxQuux", "GraultGarply", "TTTThud", "CCorgee", "Waldo",
];
Setting up the regular expression as a static that only needs to be compiled once at runtime. It's constructed from the names of the variants as provided by the strum
crate's feature.
lazy_static! {
// A Regular Expression used to find variant names in target strings.
//
static ref THING_EXPR: Regex = {
// Piece together the expression from Thing's variant names.
let expr_str = Thing::VARIANTS.join("|");
Regex::new(&expr_str).unwrap()
};
}
Example code showing how the set of strings can be iterated over and variants detected and handled. The variant name is first captured then extracted from the expression result, then the enum's variant of the same name is retrieved using the string.
fn main() {
for target in STRINGS {
if let Some(captures) = THING_EXPR.captures(target) {
// Get the substring that matched one of the variants.
let variant_name = &captures[0];
// Convert the string to the actual variant.
let variant = Thing::from_str(variant_name).unwrap();
println!("variant name: {:<8} -- variant: {:?}",
variant_name, variant);
}
}
}
Add these dependencies to the Cargo.toml file:
[dependencies]
lazy_static = "1.4"
strum = { version = "0.21", features = ["derive"] }
regex = "1.5"
output:
variant name: Quuz -- variant: Quuz
variant name: Foo -- variant: Foo
variant name: Fred -- variant: Fred
variant name: Xyzzy -- variant: Xyzzy
variant name: Plugh -- variant: Plugh
variant name: Quux -- variant: Quux
variant name: Grault -- variant: Grault
variant name: Thud -- variant: Thud
variant name: Corge -- variant: Corge
variant name: Waldo -- variant: Waldo