Created
February 18, 2020 18:26
-
-
Save lovasoa/6b211caf00ecba27abd949ff81d28328 to your computer and use it in GitHub Desktop.
A macro for cached computed fields in rust. Generates a function that checks the cached value of a field, and computes it if it's is not present.
This file contains hidden or 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
use std::fmt::Debug; | |
#[derive(Debug)] | |
struct S { | |
x: Option<u32>, | |
y: u32, | |
} | |
/// Generates a funtion named $field the returns the existing value for | |
/// $field in self if it's not None, and otherwise computes it in | |
/// self.$field (of type Option<$typ>) | |
macro_rules! cached_prop { | |
( $field:ident, $typ:ty, $compute_field:expr ) => { | |
fn $field(&mut self) -> $typ { | |
if let Some(value) = self.$field {value} | |
else { | |
let result = ($compute_field)(self); | |
self.$field = Some(result); | |
result | |
} | |
} | |
}; | |
} | |
impl S { | |
fn compute_x(&self) -> u32 { | |
self.y * 2 | |
} | |
cached_prop!{x, u32, S::compute_x} | |
} | |
fn main() { | |
let mut s = S{x:None, y:9}; | |
dbg!(&s); | |
dbg!(&s.x()); | |
dbg!(&s); | |
// This prints: | |
// s = S {x: None, y: 9,} | |
// s.x() = 18 | |
// s = S {x: Some(18), y: 9,} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment