Skip to content

Instantly share code, notes, and snippets.

@tbelaire
Forked from anonymous/playground.rs
Created December 11, 2015 18:17
Show Gist options
  • Save tbelaire/fee137d7c0696d8f6a42 to your computer and use it in GitHub Desktop.
Save tbelaire/fee137d7c0696d8f6a42 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
use std::marker::PhantomData;
enum True {}
enum False {}
enum ModeX {}
#[derive(Debug)]
struct Built<M> {
int: i32,
float: f32,
string: String,
_marker: PhantomData<M>,
}
struct Builder<S> {
int: i32,
float: Option<f32>,
string: Option<String>,
_marker: PhantomData<S>,
}
impl Builder<(False, False, False)> {
fn new(i: i32) -> Self {
Builder {
int: i,
float: None,
string: None,
_marker: PhantomData,
}
}
}
impl<A, B, C> Builder<(A, B, C)> {
fn rate(self, f: f32) -> Builder<(A, True, C)> {
Builder {
int: self.int,
float: Some(f),
string: self.string,
_marker: PhantomData,
}
}
// a label is required
fn label<T: AsRef<str>>(self, s: T) -> Builder<(True, B, C)> {
Builder {
int: self.int,
float: self.float,
string: Some(s.as_ref().to_owned()),
_marker: PhantomData,
}
}
fn ty<T>(self) -> Builder<(A, B, T)> {
Builder {
int: self.int,
float: self.float,
string: self.string,
_marker: PhantomData,
}
}
}
impl<M> Builder<(True, True, M)> {
fn finalize(self) -> Built<M> {
Built {
int: self.int,
float: self.float.unwrap(),
string: self.string.unwrap(),
_marker: PhantomData,
}
}
}
impl Built<ModeX> {
fn with_mode_x(&self) {}
}
fn main() {
let good = Builder::new(42)
.rate(3.14)
.label("hello")
.finalize();
//let bad = Builder::new(42)
// .rate(3.14)
// .finalize(); // doesn't type check
let mode = Builder::new(42)
.rate(3.14)
.label("hello")
.ty::<ModeX>()
.finalize();
mode.with_mode_x();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment