In the library I am working on I have extensively applied the following pattern. I would like to know the name of such pattern.
The library has a trait MyBounds
with a method hello
:
trait MyBounds {
type Inner;
fn hello(&mut self);
}
In the library, the trait is implemented by Base<ExtensionOne>
and Base<ExtensionTwo>
:
struct Base<E> {
extension: E,
// common fields
common: u32,
}
struct ExtensionOne;
impl MyBounds for Base<ExtensionOne> {
type Inner = ExtensionOne;
fn hello(&mut self) {
println!("hello + ExtensionOne");
let common: u32 = self.common;
// Use the specific fields contained in ExtensionOne
let extension_one: &mut ExtensionOne = &mut self.extension;
}
}
struct ExtensionTwo;
impl MyBounds for Base<ExtensionTwo> {
type Inner = ExtensionTwo;
fn hello(&mut self) {
println!("hello + ExtensionTwo");
let common: u32 = self.common;
// Use the specific fields contained in ExtensionTwo
let extension_two: &mut ExtensionTwo = &mut self.extension;
}
}
By using this pattern, the implementations of MyBounds
can access the Inner
field and implement type-specific behavior, but still share some "common" fields of Base
.
Finally, the library has the two following equivalent functions:
fn takes_mystruct<E>(mut s: Base<E>)
where
Base<E>: MyBounds,
{
s.hello();
}
fn takes_mybounds<B>(mut bounds: B)
where
B: MyBounds,
{
bounds.hello();
}
Which the user can, for example, invoke as follows.
fn main() {
takes_mybounds(Base {
extension: ExtensionOne,
common: 0,
});
takes_mybounds(Base {
extension: ExtensionTwo,
common: 0,
});
takes_base(Base {
extension: ExtensionOne,
common: 0,
});
takes_base(Base {
extension: ExtensionTwo,
common: 0,
});
}