cache_this_proc_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3
4/// `cache_this` macro enabling easy caching of expressions
5#[proc_macro]
6pub fn cache_this(input: TokenStream) -> TokenStream {
7    let cache_file_name = format!("{}", input).replace(' ', "");
8    let ast: syn::Expr = syn::parse(input).expect("Unable to parse expr");
9
10    let tokens = quote! {
11         {
12            use std::io::{Write, Read};
13            use std::path::Path;
14            use std::fs::File;
15
16            const CACHE_FOLDER_NAME : &str = ".cache-this";
17
18            let cache_file_path = Path::new(CACHE_FOLDER_NAME).join(#cache_file_name);
19
20            if cache_file_path.exists() {
21                let mut buffer = String::new();
22
23                File::open(&cache_file_path)
24                    .expect("Unable to open cached file")
25                    .read_to_string(&mut buffer)
26                    .expect("Unable to read cached file into buffer");
27
28                ::cache_this::from_str(&buffer).expect("Unable to deserialize cached result")
29            } else {
30                let result = #ast;
31
32                std::fs::create_dir_all(CACHE_FOLDER_NAME)
33                    .expect("Unable to create .cache-this folder");
34
35                let serialized_result = ::cache_this::to_string(&result).unwrap();
36                File::create(&cache_file_path)
37                    .expect("Unable to create cache file")
38                    .write_all(serialized_result.as_bytes())
39                    .expect("Unable to write cached result to file");
40
41                result
42            }
43        }
44    };
45
46    tokens.into()
47}