Skip to content

Instantly share code, notes, and snippets.

@fujitayy
Forked from rust-play/playground.rs
Created January 17, 2019 01:24
Show Gist options
  • Save fujitayy/a0417d898200c6b6c9613ee5541e1c66 to your computer and use it in GitHub Desktop.
Save fujitayy/a0417d898200c6b6c9613ee5541e1c66 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
pub mod person {
use std::marker::PhantomData;
#[derive(Debug)]
pub struct Person {
name: String,
age: u8,
}
impl Person {
pub fn builder() -> Builder<(), ()> {
Builder::new()
}
}
pub struct Builder<P1, P2> {
name: String,
age: u8,
p1: PhantomData<P1>,
p2: PhantomData<P2>,
}
impl Builder<(), ()> {
fn new() -> Builder<(), ()> {
Builder {
name: String::new(),
age: 0,
p1: PhantomData,
p2: PhantomData,
}
}
}
pub struct MarkerName;
pub struct MarkerAge;
impl<A> Builder<A, ()> {
pub fn set_age(self, age: u8) -> Builder<A, MarkerAge> {
Builder {
name: self.name,
age,
p1: self.p1,
p2: PhantomData,
}
}
}
impl<B> Builder<(), B> {
pub fn set_name<S: AsRef<str>>(self, name: S) -> Builder<MarkerName, B> {
Builder {
name: name.as_ref().to_owned(),
age: self.age,
p1: PhantomData,
p2: self.p2,
}
}
}
impl Builder<MarkerName, MarkerAge> {
pub fn build(self) -> Person {
Person {
name: self.name,
age: self.age,
}
}
}
}
use self::person::Person;
fn main() {
let person1 = Person::builder().set_age(3).set_name("ポチ").build();
let person2 = Person::builder().set_name("タマ").set_age(5).build();
// let person3 = Person::builder().set_name("コロ").build(); // compile error
println!("{:?}", person1);
println!("{:?}", person2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment