In Rust I have an enum MatchType
enum MatchType {
Exact,
Lower,
Greater,
Other,
}
I use it for my compare
function to compare two String
. If MatchType
is Exact/Lower/Greater
I want to convert both String
to f64
and compare their values (In case parse
failed I consider comparison result to be false
).
I can easily achieve it with some boilerplate code like so:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
MatchType::Exact => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one == f_two
} else {
false
}
},
MatchType::Lower => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one < f_two
} else {
false
}
},
MatchType::Greater => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
f_one > f_two
} else {
false
}
},
MatchType::Other => false,
}
}
But I wanted to try something more concise: First check if the match is one of those three Exact/Lower/Greater
then parse strings and then perform the actual comparison like so:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
MatchType::Exact | MatchType::Lower | MatchType::Greater => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
match match_type {
MatchType::Exact => f_one == f_two,
MatchType::Lower => f_one < f_two,
MatchType::Greater => f_one > f_two,
// --- Non-exhaustive ---
_ => false,
}
} else {
false
}
},
MatchType::Other => false,
}
}
It works, but the inner match is non-exhaustive, of course simple _ => false
fixes it, but I was wondering if I could somehow tell Rust compiler that the inner pattern is only those 3 enum variants Lower/Greater/Exact
.
I tried to use pattern binding like so:
fn compare(str_one: String, str_two: String, match_type: MatchType) -> bool {
match match_type {
float_match @ (MatchType::Exact | MatchType::Lower | MatchType::Greater) => {
let f_one = str_one.parse::<f64>();
let f_two = str_two.parse::<f64>();
if let (Ok(f_one), Ok(f_two)) = (f_one, f_two) {
match float_match {
MatchType::Exact => f_one == f_two,
MatchType::Lower => f_one < f_two,
MatchType::Greater => f_one > f_two,
// --- Non-exhaustive error here ---
}
} else {
false
}
},
MatchType::Other => false,
}
}
But I still get non-exhaustive
error. Any way to deal with it?