I want to provide default values for structs to be used only within tests (and not accidentally in production). I thought that I could make the defaults opt-in by defining my own trait TestDefault
and implement Default
for any type that implements it. Then, one could access all the features of the standard Default
trait using something like this
use TestDefault; // TestStruct (defined in my crate) implements TestDefault, thus also Default
let test_struct = TestStruct::default();
To clarify, I want to implement a foreign trait on local type, which should be allowed, but with an artificial layer of indirection to make it opt-in.
I've tried
pub trait TestDefault {
fn test_default() -> Self;
}
impl Default for TestDefault {
fn default() -> Self {
Self::test_default()
}
}
where the compiler complains that error[E0782]: trait objects must include the 'dyn' keyword
, inserting it instead causes it to fail because error[E0038]: the trait 'TestDefault' cannot be made into an object
.
Then I tried
impl<T> Default for T
where
T: TestDefault,
{
fn default() -> T {
T::test_default()
}
}
and got
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/lib.rs:158:14
|
158 | impl<T> Default for T
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
which probably hints at the actual error, but I don't entirely understand it. Is there any way to do this? Or get opt-in default some other way?