Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created November 3, 2017 19:48
Show Gist options
  • Save nikomatsakis/33c9b166abf74293a582ce0705f5bb5e to your computer and use it in GitHub Desktop.
Save nikomatsakis/33c9b166abf74293a582ce0705f5bb5e to your computer and use it in GitHub Desktop.
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();
}
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