Skip to content

Instantly share code, notes, and snippets.

@luser
Forked from anonymous/playground.rs
Created May 27, 2016 11:15
Show Gist options
  • Save luser/e66b3e624f32a8bcef8263dcd69c98e8 to your computer and use it in GitHub Desktop.
Save luser/e66b3e624f32a8bcef8263dcd69c98e8 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
use std::marker::PhantomData;
use std::boxed::Box;
trait Data {
fn get(&self) -> u32;
}
trait DataCreator {
fn new_data() -> Box<Data>;
}
struct Thing<T = DataCreatorOne> {
pub x: u32,
pub d: Box<Data>,
_p: PhantomData<*const T>,
}
impl Thing<DataCreatorOne> {
pub fn new(x: u32) -> Thing<DataCreatorOne> {
Thing {
x: x,
d: DataCreatorOne::new_data(),
_p: PhantomData,
}
}
}
impl<T> Thing<T> where T: DataCreator {
pub fn with_creator(x: u32) -> Thing<T> {
Thing {
x: x,
d: T::new_data(),
_p: PhantomData,
}
}
}
struct DataCreatorOne;
struct DataOne;
impl Data for DataOne {
fn get(&self) -> u32 { 1 }
}
impl DataCreator for DataCreatorOne {
fn new_data() -> Box<Data> {
Box::new(DataOne)
}
}
struct DataCreatorTwo;
struct DataTwo;
impl Data for DataTwo {
fn get(&self) -> u32 { 2 }
}
impl DataCreator for DataCreatorTwo {
fn new_data() -> Box<Data> {
Box::new(DataTwo)
}
}
fn main() {
let t = Thing::new(10);
println!("t.x: {}, t.d.get(): {}", t.x, t.d.get());
let t = Thing::<DataCreatorOne>::with_creator(10);
println!("t.x: {}, t.d.get(): {}", t.x, t.d.get());
let t = Thing::<DataCreatorTwo>::with_creator(20);
println!("t.x: {}, t.d.get(): {}", t.x, t.d.get());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment