Skip to content

Instantly share code, notes, and snippets.

@sug0
Last active April 24, 2022 21:05
Show Gist options
  • Save sug0/15f7eb4d6cb75d6c5e661eb639fb058f to your computer and use it in GitHub Desktop.
Save sug0/15f7eb4d6cb75d6c5e661eb639fb058f to your computer and use it in GitHub Desktop.
Specialization idiom in stable Rust
use std::fmt::Debug;
use std::marker::PhantomData;
enum Specialized {}
enum Generic {}
struct Thing<T, K = Generic> {
inner: T,
_phantom: PhantomData<K>,
}
trait ThingImpl<T> {
fn the_thing(&self)
where
T: Debug;
}
fn main() {
let thing: Thing<&'static str, Generic> = Thing::new("jarda");
consume_thing(&thing);
let thing: Thing<i32, Generic> = Thing::new(420);
consume_thing(&thing);
let thing: Thing<i32, Specialized> = Thing::new(69);
consume_thing(&thing);
let thing: Thing<bool, Specialized> = Thing::new(false);
consume_thing(&thing);
}
fn consume_thing<T, K>(thing: &Thing<T, K>)
where
Thing<T, K>: ThingImpl<T>,
T: Debug,
{
thing.the_thing();
thing.the_thang();
}
impl<T, K> Thing<T, K> {
fn new(inner: T) -> Self {
Self { inner, _phantom: PhantomData }
}
fn the_thang(&self) {
println!("Shared: the thang!");
}
}
impl<T> ThingImpl<T> for Thing<T, Generic> {
fn the_thing(&self)
where
T: Debug,
{
println!("Generic: {:?}", self.inner);
}
}
impl ThingImpl<i32> for Thing<i32, Specialized> {
fn the_thing(&self) {
println!("Specialized i32: {:?}", self.inner);
}
}
impl ThingImpl<bool> for Thing<bool, Specialized> {
fn the_thing(&self) {
println!("Specialized bool: {:?}", self.inner);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment