Created
November 3, 2017 19:48
-
-
Save nikomatsakis/33c9b166abf74293a582ce0705f5bb5e to your computer and use it in GitHub Desktop.
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; | |
trait Task { | |
type Output; | |
type Error; | |
fn execute(self) -> Result<Self::Output, Self::Error>; | |
fn and_then<F, B>(self, task: F) -> AndThenTask<Self, B, F> | |
where | |
F: FnOnce(Self::Output) -> B, | |
B: Task<Error = Self::Error>, | |
Self: Sized, | |
{ | |
AndThenTask { | |
a: self, | |
closure: task, | |
data: PhantomData, | |
} | |
} | |
} | |
trait IntoTask {} | |
struct HelloWorldTask; | |
impl Task for HelloWorldTask { | |
type Output = (); | |
type Error = (); | |
fn execute(self) -> Result<Self::Output, Self::Error> { | |
println!("Hello, world!"); | |
Ok(()) | |
} | |
} | |
struct AndThenTask<A, B, F> { | |
a: A, | |
closure: F, | |
data: PhantomData<fn() -> B>, | |
} | |
impl<A, B, F> Task for AndThenTask<A, B, F> | |
where | |
A: Task, | |
B: Task<Error = A::Error>, | |
F: FnOnce(A::Output) -> B, | |
{ | |
type Output = B::Output; | |
type Error = A::Error; | |
fn execute(self) -> Result<B::Output, B::Error> { | |
let a_result = self.a.execute()?; | |
let b_task = (self.closure)(a_result); | |
b_task.execute() | |
} | |
} | |
macro_rules! slow { | |
(@($f:expr) ()) => { | |
$f | |
}; | |
(@($f:expr) ($name:tt $($names:tt)*)) => { | |
slow!(@($f.and_then(|()| HelloWorldTask)) ($($names)*)) | |
}; | |
($($names:tt)*) => { | |
slow!(@(HelloWorldTask) ($($names)*)) | |
}; | |
} | |
fn main() { | |
#[cfg(size0)] | |
let f = slow! { }; | |
#[cfg(size4)] | |
let f = slow! { | |
a b c d | |
}; | |
#[cfg(size8)] | |
let f = slow! { | |
a b c d | |
a b c d | |
}; | |
#[cfg(size12)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
}; | |
#[cfg(size16)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
a b c d | |
}; | |
#[cfg(size32)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
a b c d | |
}; | |
f.execute().unwrap(); | |
} |
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; | |
trait Task { | |
type Error; | |
fn execute(self) -> Result<(), Self::Error>; | |
fn and_then<F, B>(self, task: F) -> AndThenTask<Self, B, F> | |
where | |
F: FnOnce() -> B, | |
B: Task<Error = Self::Error>, | |
Self: Sized, | |
{ | |
AndThenTask { | |
a: self, | |
closure: task, | |
data: PhantomData, | |
} | |
} | |
} | |
trait IntoTask {} | |
struct HelloWorldTask; | |
impl Task for HelloWorldTask { | |
type Error = (); | |
fn execute(self) -> Result<(), Self::Error> { | |
println!("Hello, world!"); | |
Ok(()) | |
} | |
} | |
struct AndThenTask<A, B, F> { | |
a: A, | |
closure: F, | |
data: PhantomData<fn() -> B>, | |
} | |
impl<A, B, F> Task for AndThenTask<A, B, F> | |
where | |
A: Task, | |
B: Task<Error = A::Error>, | |
F: FnOnce() -> B, | |
{ | |
type Error = A::Error; | |
fn execute(self) -> Result<(), B::Error> { | |
self.a.execute()?; | |
let b_task = (self.closure)(); | |
b_task.execute() | |
} | |
} | |
macro_rules! slow { | |
(@($f:expr) ()) => { | |
$f | |
}; | |
(@($f:expr) ($name:tt $($names:tt)*)) => { | |
slow!(@($f.and_then(|| HelloWorldTask)) ($($names)*)) | |
}; | |
($($names:tt)*) => { | |
slow!(@(HelloWorldTask) ($($names)*)) | |
}; | |
} | |
fn main() { | |
#[cfg(size4)] | |
let f = slow! { | |
a b c d | |
}; | |
#[cfg(size8)] | |
let f = slow! { | |
a b c d | |
a b c d | |
}; | |
#[cfg(size12)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
}; | |
#[cfg(size16)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
a b c d | |
}; | |
#[cfg(size32)] | |
let f = slow! { | |
a b c d | |
a b c d | |
a b c d | |
a b c d | |
}; | |
f.execute().unwrap(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment