I have an example of a type which contains a configurable function with a default implementation. This compiles and runs fine as long as the [derive(PartialEq)]
is commented out. If it's not commented out, I get errors:
type StringMunger = fn(&str) -> String;
fn default_string_munger(s: &str) -> String {
format!("Hello, {}!", s)
}
#[derive(PartialEq)]
struct Thing {
string_munger: StringMunger,
}
impl Thing {
fn new() -> Self {
Self{string_munger: default_string_munger}
}
fn munge(&mut self, s: &str) -> String {
(self.string_munger)(s)
}
}
fn main() {
let mut thing = Thing::new();
println!("{}", thing.munge("world"));
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0277]: `for<'r> fn(&'r str) -> std::string::String` doesn't implement `std::fmt::Debug`
--> src/main.rs:9:5
|
9 | string_munger: StringMunger,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `for<'r> fn(&'r str) -> std::string::String` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `for<'r> fn(&'r str) -> std::string::String`
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&for<'r> fn(&'r str) -> std::string::String`
= note: required for the cast to the object type `dyn std::fmt::Debug`
error[E0369]: binary operation `==` cannot be applied to type `for<'r> fn(&'r str) -> std::string::String`
--> src/main.rs:9:5
|
9 | string_munger: StringMunger,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `for<'r> fn(&'r str) -> std::string::String`
error[E0369]: binary operation `!=` cannot be applied to type `for<'r> fn(&'r str) -> std::string::String`
--> src/main.rs:9:5
|
9 | string_munger: StringMunger,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: an implementation of `std::cmp::PartialEq` might be missing for `for<'r> fn(&'r str) -> std::string::String`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0277, E0369.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
If I naïvely try to add
impl PartialEq for StringMunger {
fn eq(&self, other: &Self) -> bool {
false
}
}
then I get a different error:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:12:1
|
12 | impl PartialEq for StringMunger {
| ^^^^^---------^^^^^------------
| | | |
| | | `for<'r> fn(&'r str) -> std::string::String` is not defined in the current crate
| | `for<'r> fn(&'r str) -> std::string::String` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
Of course, I want to implement PartialEq
, Debug
etc. for Thing
, but I can't derive them automagically because of the use of the function type. How do I achieve the ability to implement those traits for Thing
as easily as possible?