I think if you only need to match a few strings, then an if ... else if tree or Martin's solution is probably best. Otherwise, I don't think there is a way to match string slice prefixes using match.
If, however, you have many strings you need to match, I'd recommend AhoCorasick, which will be algorithmically optimal. You can use the aho-corasick crate.
use aho_corasick::{AhoCorasick, AhoCorasickBuilder, MatchKind};
const PATTERNS: &[&str] = &["OR", "AND"];
fn op<T: AsRef<[u8]>>(ac: &AhoCorasick, v: T) -> Option<&'static str> {
ac.find(v).map(|m| PATTERNS[m.pattern()])
}
fn main() {
let ac = AhoCorasickBuilder::new()
.auto_configure(PATTERNS)
.anchored(true)
.match_kind(MatchKind::LeftmostFirst)
.build(PATTERNS);
println!(
"{:?} / {:?} / {:?}",
op(&ac, "OR"),
op(&ac, "AND"),
op(&ac, "XOR")
)
}
The trick to make it work for prefixes here is to set anchored(true). This will ensure that any match returned must be anchored to the beginning of the haystack.
The LeftmostFirst match kind setting may not be necessary, but it instructs the matcher to prefer earlier patterns over later patterns. e.g., if your patterns are Samwise and Sam, then LeftmostFirst will ensure that Samwise matches Samwise and not Sam. If none of your patterns have overlapping prefixes, then you can remove this setting.
Finally, the auto_configure option will enable some optimizations in the automaton, such as using a DFA instead of an NFA if the number of patterns is small enough.
See it also on the playground.