Skip to content

Instantly share code, notes, and snippets.

@fero23
Created May 25, 2016 06:50
Show Gist options
  • Save fero23/6d59b18c65e0ea7cad589cc4ff1646b5 to your computer and use it in GitHub Desktop.
Save fero23/6d59b18c65e0ea7cad589cc4ff1646b5 to your computer and use it in GitHub Desktop.
use std::collections::HashMap;
trait Resolver {
type Input;
fn resolve<'a, T: FromInput<Self::Input>>(&self, name: &'a str) -> T;
}
trait FromInput<T> {
fn from(s: T) -> Self;
}
macro_rules! models {
{$(def $name:ident from $source_t:ty {$($prop:ident : $t:ty),*})*} => {
$(
#[derive(Debug)]
struct $name {
$($prop: $t),*
}
impl $name {
fn from_source<'a>(source: &'a $source_t) -> $name {
$name {
$($prop: source.resolve(stringify!($prop))),*
}
}
}
)*
};
}
impl Resolver for HashMap<String, String> {
type Input = String;
fn resolve<'a, T: FromInput<String>>(&self, name: &'a str) -> T {
T::from(self[name].clone())
}
}
impl FromInput<String> for u32 {
fn from(s: String) -> u32 {
s.parse().unwrap()
}
}
impl FromInput<String> for String {
fn from(s: String) -> String {
s
}
}
models! {
def Person from HashMap<String, String> {
id: u32,
name: String,
last_name: String
}
}
fn main() {
let mut map = HashMap::new();
map.insert("id".to_string(), 1.to_string());
map.insert("name".to_string(), "Fernando".to_string());
map.insert("last_name".to_string(), "Ulloa".to_string());
let person = Person::from_source(&map);
println!("{:?}", person);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment