Last active
November 13, 2016 16:59
-
-
Save anowell/f7b1251c123309a5515f411a03d55572 to your computer and use it in GitHub Desktop.
First draft experiment at reducing boilerplate for algorithm entrypoint
This file contains 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
/* | |
Example usage: | |
Note: in all of these cases, the return value must be `Result<T, E>` where: | |
- `T` has a conversion to `AlgoOutput` (e.g. String, Vec<u8>, JsonValue, (), or anything Serializeable) | |
- `E` has a conversion to `Box<Error>` (e.g. String or any custom type that `impl Error`) | |
-------------Text----------------------- | |
algo_entrypoint! { text => hello } | |
fn hello(input: &str) -> Result<String, String> { | |
Ok(format!("Hello {}", input)) | |
} | |
-------------JSON----------------------- | |
algo_entrypoint! { json => foo } | |
fn foo(input: JsonValue) -> Result<JsonValue, String> { | |
Ok(input) | |
} | |
-------------Binary----------------------- | |
algo_entrypoint! { bytes => foo } | |
fn foo(input: &[u8]) -> Result<u64, String> { | |
Ok(input.len() as u64) | |
} | |
-------------Auto-Decode----------------------- | |
#[derive(RustcDecodable)] | |
struct MyInput { field: String }; | |
#[derive(RustcEncodable)] | |
struct MyOutput { field: u32 }; | |
algo_entrypoint! { MyInput => foo } | |
fn foo(input: MyInput) -> Result<MyOutput, String> { | |
Ok(MyOutput { | |
field: input.field.len() as u32 | |
}) | |
} | |
-------------One-time init with state----------------------- | |
pub struct Algo { uuid: String }; | |
algo_entrypoint! { text => Algo::hello } | |
impl Algo { | |
fn hello(&self, input: &str) -> Result<String, String> { | |
Ok(format!("Hello {} - {}", input, self.uuid)) | |
} | |
} | |
impl Default for Algo { | |
fn default() -> Algo { | |
Algo { uuid: uuid::gen_uuid() } | |
} | |
} | |
*/ | |
#[macro_export] | |
macro_rules! algo_entrypoint { | |
// Helpers for recursively implementing text/bytes/JsonValue/AlgoInput | |
($t:ty, $apply:ident, Algo::$method:ident) => { | |
impl EntryPoint for Algo { | |
fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> { | |
self.$method(input).map(AlgoOutput::from).map_err(|err| err.into()) | |
} | |
} | |
}; | |
($t:ty, $apply:ident, $p:path) => { | |
#[derive(Default)] pub struct Algo; | |
impl EntryPoint for Algo { | |
fn $apply(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> { | |
$p(input).map(AlgoOutput::from).map_err(|err| err.into()) | |
} | |
} | |
}; | |
// Implement EntryPoint to call methods on `Algo` | |
(text => Algo::$i:ident) => { | |
algo_entrypoint!(&str, apply_str, Algo::$i); | |
}; | |
(bytes => Algo::$i:ident) => { | |
algo_entrypoint!(&[u8], apply_bytes, Algo::$i); | |
}; | |
(json => Algo::$i:ident) => { | |
algo_entrypoint!(::algorithmia::algo::JsonValue, apply_json, Algo::$i); | |
}; | |
(AlgoInput => Algo::$i:ident) => { | |
algo_entrypoint!(::algorithmia::AlgoInput, apply, Algo::$i); | |
}; | |
($t:ty => Algo::$i:ident) => { | |
impl DecodedEntryPoint for Algo { | |
type Input = $t; | |
fn apply_bytes(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> { | |
self.$i(input).map(AlgoOutput::from).map_err(|err| err.into()) | |
} | |
} | |
}; | |
// Implement EntryPoint to call free functions | |
(text => $i:ident) => { | |
algo_entrypoint!(&str, apply_str, $i); | |
}; | |
(bytes => $i:ident) => { | |
algo_entrypoint!(&[u8], apply_bytes, $i); | |
}; | |
(json => $i:ident) => { | |
algo_entrypoint!(::algorithmia::algo::JsonValue, apply_json, $i); | |
}; | |
(AlgoInput => $i:ident) => { | |
algo_entrypoint!(::algorithmia::AlgoInput, apply, $i); | |
}; | |
($t:ty => $p:path) => { | |
#[derive(Default)] pub struct Algo; | |
impl DecodedEntryPoint for Algo { | |
type Input = $t; | |
fn apply_decoded(&self, input: $t) -> Result<AlgoOutput, Box<::std::error::Error>> { | |
$p(text).map(AlgoOutput::from).map_err(|err| err.into()) | |
} | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment