Reputation: 4618
I'm trying to create a struct that looks like this:
struct MediaLibrary<B>
where
B: Ord,
{
root_dir: PathBuf,
item_meta_fn: String,
self_meta_fn: String,
media_item_filter: fn(&Path) -> bool,
media_item_sort_key: fn(&Path) -> B,
}
The last two fields are meant to be used as a predicate to test if a given path is a valid media file and to sort a vector of paths (using sort_by_key
), respectively.
However, as it is right now, the design is inflexible: both functions are fixed to accept only Path
. I'd like to be able to use P: AsRef<Path>
as the stdlib uses for many of its file and path methods, but I'm not sure how to add this.
A number of the methods I've impl
'd for MediaLibrary
are already using P: AsRef<Path>
for their arguments, so my gut feeling tells me that there would be conflicts.
Upvotes: 2
Views: 3363
Reputation: 430673
To my knowledge, you cannot have a function pointer with a generic type, I don't even think such a construct is accepted by the Rust parser.
Furthermore, you cannot simply switch to extra type parameters on the struct as they would be unused by the struct itself:
struct MediaLibrary<F, P1, K, P2, B>
where
F: Fn(P1) -> bool,
P1: AsRef<Path>,
K: Fn(P2) -> B,
P2: AsRef<Path>,
B: Ord,
{
root_dir: PathBuf,
item_meta_fn: String,
self_meta_fn: String,
media_item_filter: F,
media_item_sort_key: K,
}
error[E0392]: parameter `P1` is never used
--> src/main.rs:3:24
|
3 | struct MediaLibrary<F, P1, K, P2, B>
| ^^ unused type parameter
|
= help: consider removing `P1` or using a marker such as `std::marker::PhantomData`
Instead, you can choose to apply the constraints only on the functions where they are used:
struct MediaLibrary<F> {
media_item_filter: F,
}
impl<F> MediaLibrary<F> {
fn do_filter<P>(&self)
where
F: Fn(P) -> bool,
P: AsRef<Path>,
{}
}
As the message states, you could also use PhantomData
.
Upvotes: 4