Skip to content

Instantly share code, notes, and snippets.

@sjkillen
Created December 21, 2023 19:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sjkillen/1c42fd3e567264fdacc973fe18a7e46e to your computer and use it in GitHub Desktop.
Save sjkillen/1c42fd3e567264fdacc973fe18a7e46e to your computer and use it in GitHub Desktop.
Odd but useful Rust pattern to implement abstract methods and extend structs with additional fields
struct Base<Extension = ()> {
ext: Extension,
x: i32,
y: i32,
z: i32,
}
trait BaseAbstractMethods {
fn combine_components(&self, a: i32, b: i32) -> i32;
}
impl<Ext> Base<Ext>
where
Self: BaseAbstractMethods,
{
fn combine_all(&self) -> i32 {
self.combine_components(self.x, self.combine_components(self.y, self.z))
}
}
struct BasicAddingCombiner;
impl BaseAbstractMethods for Base<BasicAddingCombiner> {
fn combine_components(&self, a: i32, b: i32) -> i32 {
a + b
}
}
struct TakeCloserToTarget {
target: i32,
}
impl BaseAbstractMethods for Base<TakeCloserToTarget> {
fn combine_components(&self, a: i32, b: i32) -> i32 {
if (a - self.ext.target).abs() < (b - self.ext.target).abs() {
a
} else {
b
}
}
}
fn main() {
let adder = Base {
ext: BasicAddingCombiner,
x: 1,
y: 2,
z: 3,
};
println!("{}", adder.combine_all());
let closer = Base {
ext: TakeCloserToTarget { target: 42 },
x: 45,
y: 70,
z: 41,
};
println!("{}", closer.combine_all());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment