Skip to content

Instantly share code, notes, and snippets.

@killercup
Last active May 31, 2018 14:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save killercup/432651935f3bb53ee5b62b5cec242fc7 to your computer and use it in GitHub Desktop.
Save killercup/432651935f3bb53ee5b62b5cec242fc7 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 {
($field:ident ($ty:ty) to $subresource:ident) => {
fn $field(&self) -> &$ty {
&self.$subresource.$field
}
}
}
enum Availability { Available, NotAvailable }
struct Variant {
color: String,
availability: Availability,
}
struct SpecificProduct {
title: String,
variant: Variant,
}
impl SpecificProduct {
fn title(&self) -> &str { &self.title }
delegate!(color (String) to variant);
delegate!(availability (Availability) to variant);
}
#[test]
fn success() {
let prod = SpecificProduct {
title: "Thingy".into(),
variant: Variant {
color: "Blue".into(),
availability: Availability::NotAvailable,
},
};
assert_eq!(prod.color(), &"Blue".to_string());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment