I have a trait called Sleep
:
pub trait Sleep {
fn sleep(&self);
}
I could provide a different implementation of sleep for every struct, but it turns out that most people sleep in a very small number of ways. You can sleep in a bed:
pub trait HasBed {
fn sleep_in_bed(&self);
fn jump_on_bed(&self);
}
impl Sleep for HasBed {
fn sleep(&self) {
self.sleep_in_bed()
}
}
If you're camping, you can sleep in a tent:
pub trait HasTent {
fn sleep_in_tent(&self);
fn hide_in_tent(&self);
}
impl Sleep for HasTent {
fn sleep(&self) {
self.sleep_in_tent()
}
}
There are some oddball cases. I have a friend that can sleep standing against a wall, but most people, most of the time, fall into some simple case.
We define some structs and let them sleep:
struct Jim;
impl HasBed for Jim {
fn sleep_in_bed(&self) {}
fn jump_on_bed(&self) {}
}
struct Jane;
impl HasTent for Jane {
fn sleep_in_tent(&self) {}
fn hide_in_tent(&self) {}
}
fn main() {
use Sleep;
let jim = Jim;
jim.sleep();
let jane = Jane;
jane.sleep();
}
Uh-oh! Compile error:
error[E0599]: no method named `sleep` found for type `Jim` in the current scope
--> src/main.rs:44:9
|
27 | struct Jim;
| ----------- method `sleep` not found for this
...
44 | jim.sleep();
| ^^^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `sleep`, perhaps you need to implement it:
candidate #1: `Sleep`
error[E0599]: no method named `sleep` found for type `Jane` in the current scope
--> src/main.rs:47:10
|
34 | struct Jane;
| ------------ method `sleep` not found for this
...
47 | jane.sleep();
| ^^^^^
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `sleep`, perhaps you need to implement it:
candidate #1: `Sleep`
This compiler error is strange because if there was something wrong with a trait implementing another trait, I expected to hear about it way back when I did that, not at the very bottom of the program when I try to use the result.
In this example, there are only 2 structs and 2 ways to sleep, but in the general case there are many structs and several ways to sleep (but not as many ways as there are structs).
A Bed
is mostly an implementation for Sleep
, but in the general case a Bed
has many uses and could implement many things.
The only immediately obvious approach is to convert impl Sleep for...
into a macro that structs themselves use, but that seems hacky and terrible.