I have an enum and a generic function that takes a constructor for the enum and a callable that returns constructor arguments
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
enum Snapshot {
APath(std::path::PathBuf),
ManyPaths(Vec<std::path::PathBuf>),
}
fn compute_or_lookup<Callable, Constructor, ConstructorArgument>(
construct: Constructor,
compute: Callable,
already_done: &mut Vec<Snapshot>,
) -> ConstructorArgument
where
Callable: FnOnce() -> ConstructorArgument,
Constructor: FnOnce(&ConstructorArgument) -> Snapshot,
{
match already_done
.iter()
.find_map(|x| match x {
construct(argument) => Some(argument),
_ => None,
})
{
Some(x) => x,
None => {
let retval = compute();
already_done.push(construct(&retval));
retval
}
}
}
i.e. I have a compute intense path that calls the callable, constructs an enum with the callable's return, and inserts it into the vector. As a shortcut I want to check if that operation has already been done. (We can assume that each enum variant will only be constructed once).
The above example however does not compile because
--> src/main.rs:21:13
|
21 | construct(argument) => Some(argument),
| ^^^^^^^^^ not a tuple struct or tuple variant
Is there a way i can match on "the enum that gets returned by the given constructor"?
EDIT:
as a usage example, I would want to call
fn some_function() -> std::path::PathBuf ....
fn main() {
let mut some_vector : Vec<Snapshot> = ...;
let _ = compute_or_lookup(Snapshot::APath, some_function, &some_vector);
}
i.e. in the match i would want to evaluate something like
match x {
Snapshot::APath(p) => Some(p),
_ => None
}
or
match x {
Snapshot::ManyPaths(v) => Some(v),
_ => None
}
just the Snapshot::ManyPaths
or Snapshot::APath
replaced by the at-code-write-time-unknown constructor
.