Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pacmancoder/283059c31f8d756b097f86c14b4c24bf to your computer and use it in GitHub Desktop.
Save pacmancoder/283059c31f8d756b097f86c14b4c24bf to your computer and use it in GitHub Desktop.
Compile-time type generation with trait requirements
use std::marker::PhantomData;
struct Unconcrete;
struct One;
struct Two;
struct Three;
struct Four;
struct Five;
fn new_configurator<T>() -> Configurator<T, Unconcrete> {
Configurator {
_phantom_data: PhantomData,
_phantom_child: PhantomData,
}
}
struct Configurator<T, Child> {
_phantom_data: PhantomData<T>,
_phantom_child: PhantomData<Child>,
}
impl<T, Child> Configurator<T, Child> {
pub fn join<U>(self) -> Configurator<U, Self> {
Configurator {
_phantom_data: PhantomData,
_phantom_child: PhantomData,
}
}
}
trait SayHello {
fn say_hello(&self) {
println!("Hello!");
}
}
impl SayHello for Unconcrete {}
impl SayHello for One {}
impl SayHello for Two {}
impl SayHello for Three {}
impl<T, Child> SayHello for Configurator<T, Child> where T: SayHello, Child: SayHello {}
trait SayGoodbye {
fn say_good_bye(&self) {
println!("Good bye!");
}
}
impl SayGoodbye for Unconcrete {}
impl SayGoodbye for Two {}
impl SayGoodbye for Three {}
impl SayGoodbye for Five {}
impl<T, Child> SayGoodbye for Configurator<T, Child> where T: SayGoodbye, Child: SayGoodbye {}
fn main() {
// Case I: all types implement required types
let configurator = new_configurator::<Two>().join::<Three>();
configurator.say_hello();
configurator.say_good_bye();
// Case II: SayHello implemented by some type
let configurator = new_configurator::<Two>().join::<Five>();
//configurator.say_hello(); <----- ERROR: method not found
configurator.say_good_bye();
// Case III: SayGoodbye implemented by some type
let configurator = new_configurator::<One>().join::<Three>();
configurator.say_hello();
//configurator.say_good_bye(); <----- ERROR: method not found
// Case III: SayGoodbye and SayHello are not implemented by some type
let configurator = new_configurator::<Two>().join::<Four>();
//configurator.say_hello(); <----- ERROR: method not found
//configurator.say_good_bye(); <----- ERROR: method not found
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment