Skip to content

Instantly share code, notes, and snippets.

@naithar
Forked from killercup/playground.rs
Last active May 31, 2018 14:31
Show Gist options
  • Save naithar/775fc2f5d71199606e9bd9331f955b34 to your computer and use it in GitHub Desktop.
Save naithar/775fc2f5d71199606e9bd9331f955b34 to your computer and use it in GitHub Desktop.
#![allow(dead_code)]
/// Create method to access field of sub-resource
///
/// Similar to ActiveSupport's [`delegate`].
///
/// [`delegate`]: http://api.rubyonrails.org/classes/Module.html#method-i-delegate
///
/// # Limitations
///
/// - You need to specify the return type
/// - No prefixing, because `concat_idents` is [useless]
///
/// [useless]: https://github.com/rust-lang/rust/issues/29599
macro_rules! delegate {
(var $field:ident -> ($ty:ty) to $subresource:ident) => {
fn $field(&self) -> $ty {
&self.$subresource.$field
}
};
(func $function:ident : ($($p:ident : $pt:ty),*) -> () to $subresource:ident) => {
fn $function(&self, $($p: $pt),*) {
self.$subresource.$function($($p),*)
}
};
(func $function:ident : ($($p:ident : $pt:ty),*) -> ($ty:ty) to $subresource:ident) => {
fn $function(&self, $($p: $pt),*) -> $ty {
&self.$subresource.$function($($p),*)
}
};
(func $function:ident<$($l:lifetime),*> : ($($p:ident : $pt:ty),*) -> () to $subresource:ident) => {
fn $function<$($l),*>(&self, $($p: $pt),*) {
self.$subresource.$function($($p),*)
}
};
(func $function:ident<$($l:lifetime),*> : ($($p:ident : $pt:ty),*) -> ($ty:ty) to $subresource:ident) => {
fn $function<$($l),*>(&self, $($p: $pt),*) -> $ty {
&self.$subresource.$function($($p),*)
}
};
}
enum Availability { Available, NotAvailable }
struct Variant {
color: String,
availability: Availability,
}
struct SpecificProduct {
title: String,
variant: Variant,
}
impl Variant {
fn color_string(&self) -> &str {
return &self.color
}
fn color_string1(&self, val: &str) {
println!("{}", val)
}
fn color_string2(&self, val: &str) -> &str {
println!("{}", val);
return &self.color
}
fn color_string3<'a>(&self, val: &'a str) -> &'a str {
return val
}
}
impl SpecificProduct {
fn title(&self) -> &str { &self.title }
delegate!(var color -> (&String) to variant);
delegate!(var availability -> (&Availability) to variant);
delegate!(func color_string : () -> (&str) to variant);
delegate!(func color_string1 : (val : &str) -> () to variant);
delegate!(func color_string3<'a> : (val : &'a str) -> (&'a str) to variant);
}
#[test]
fn success() {
let prod = SpecificProduct {
title: "Thingy".into(),
variant: Variant {
color: "Blue".into(),
availability: Availability::NotAvailable,
},
};
let a: &str = "Blue".into();
prod.color_string3(a);
assert_eq!(prod.color_string(), &"Blue".to_string());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment