Created
July 24, 2017 13:16
-
-
Save nesteruk/d1fcfbd8d9fbedce27a478a26a8d65cf to your computer and use it in GitHub Desktop.
Fluent builder with lifetime/references removed... doesn't compile.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::marker::PhantomData; | |
use std::rc::Rc; | |
use std::fmt::Display; | |
struct Person | |
{ | |
street_address: String, | |
postcode: String, | |
city: String, | |
company_name: String, | |
position: String, | |
annual_income: usize | |
} | |
impl ToString for Person | |
{ | |
fn to_string(&self) -> String | |
{ | |
format!("I live at {}, {}, {} and work as a {} at {} earning {}", | |
self.street_address, self.city, self.postcode, | |
self.company_name, self.position, self.annual_income) | |
} | |
} | |
struct PersonBuilder | |
{ | |
person: Person | |
} | |
impl PersonBuilder | |
{ | |
fn new() -> PersonBuilder | |
{ | |
PersonBuilder { | |
person: Person { | |
street_address: String::new(), | |
postcode: String::new(), | |
city: String::new(), | |
company_name: String::new(), | |
position: String::new(), | |
annual_income: 0 | |
} | |
} | |
} | |
} | |
trait Builder | |
{ | |
fn lives(&self) -> PersonAddressBuilder; | |
fn works(&self) -> PersonJobBuilder; | |
} | |
macro_rules! impl_Builder | |
{ | |
($T:ty) => | |
{ | |
impl Builder for $T | |
{ | |
fn lives(&self) -> PersonAddressBuilder | |
{ | |
PersonAddressBuilder::new(self.person) | |
} | |
fn works(&self) -> PersonJobBuilder | |
{ | |
PersonJobBuilder::new(self.person) | |
} | |
} | |
// | |
// impl<$L> Into<Person<$L>> for $T | |
// { | |
// fn into(self) -> $T | |
// { | |
// self.person | |
// } | |
// } | |
} | |
} | |
struct PersonAddressBuilder | |
{ | |
person: Person | |
} | |
impl PersonAddressBuilder | |
{ | |
fn new(person: Person) -> PersonAddressBuilder | |
{ | |
PersonAddressBuilder { person: person } | |
} | |
fn at(&self, street_address: &str) -> &PersonAddressBuilder | |
{ | |
self.person.street_address = street_address.to_string(); | |
self | |
} | |
fn with_postcode(&self, postcode: &str) -> &PersonAddressBuilder | |
{ | |
self.person.postcode = postcode.to_string(); | |
self | |
} | |
fn in_city(&self, city: &str) -> &PersonAddressBuilder | |
{ | |
self.person.city = city.to_string(); | |
self | |
} | |
} | |
struct PersonJobBuilder | |
{ | |
person: Person | |
} | |
impl PersonJobBuilder | |
{ | |
fn new(person: Person) -> PersonJobBuilder | |
{ | |
PersonJobBuilder { person: person } | |
} | |
fn at(&self, company_name: &str) -> &PersonJobBuilder | |
{ | |
self.person.company_name = company_name.to_string(); | |
self | |
} | |
fn as_a(&self, position: &str) -> &PersonJobBuilder | |
{ | |
self.person.position = position.to_string(); | |
self | |
} | |
fn earning(&self, annual_income: usize) -> &PersonJobBuilder | |
{ | |
self.person.annual_income = annual_income; | |
self | |
} | |
} | |
impl_Builder!(PersonBuilder); | |
impl_Builder!(PersonJobBuilder); | |
impl_Builder!(PersonAddressBuilder); | |
fn main() | |
{ | |
let pb = PersonBuilder::new(); | |
let p = pb | |
.lives() | |
.at("123 London Road") | |
.in_city("London") | |
.with_postcode("PO12SW") | |
.works() | |
.at("Fabrikam") | |
.as_a("Developer") | |
.earning(123000) | |
.person; | |
println!("{}", p.to_string()); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment