From 0196b5e1039224d3b55699cd054e14f852036fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Zmarz=C5=82y?= Date: Sat, 14 Sep 2019 13:35:11 +0200 Subject: [PATCH 1/2] Add optional caching --- markup-proc-macro/Cargo.toml | 5 +++++ markup-proc-macro/src/caching.rs | 33 ++++++++++++++++++++++++++++++++ markup-proc-macro/src/lib.rs | 11 ++++++++--- markup/Cargo.toml | 3 +++ 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 markup-proc-macro/src/caching.rs diff --git a/markup-proc-macro/Cargo.toml b/markup-proc-macro/Cargo.toml index 7a39e27..45cc095 100644 --- a/markup-proc-macro/Cargo.toml +++ b/markup-proc-macro/Cargo.toml @@ -16,3 +16,8 @@ proc-macro = true proc-macro2 = "1.0.3" quote = "1.0.2" syn = { version = "1.0.5", features = ["extra-traits", "full"] } +sha2 = { version = "0.8", optional = true } +dirs = { version = "2.0.2", optional = true } + +[features] +caching = ["sha2", "dirs"] diff --git a/markup-proc-macro/src/caching.rs b/markup-proc-macro/src/caching.rs new file mode 100644 index 0000000..d6bb4e2 --- /dev/null +++ b/markup-proc-macro/src/caching.rs @@ -0,0 +1,33 @@ +use proc_macro::TokenStream; + +#[cfg(not(feature = "caching"))] +pub fn cached(tokens: TokenStream, f: impl FnOnce(TokenStream) -> TokenStream) -> TokenStream { + f(tokens) +} + +#[cfg(feature = "caching")] +pub fn cached(tokens: TokenStream, f: impl FnOnce(TokenStream) -> TokenStream) -> TokenStream { + use sha2::{Digest, Sha256}; + use std::fs; + + let dir = dirs::cache_dir().unwrap().join("markup-rs"); + let _ = fs::create_dir(&dir); + + let input = tokens.to_string(); + let mut hasher = Sha256::new(); + hasher.input(input); + let hash = hasher.result(); + let path = dir.join(format!("{:x}", hash)); + + if let Ok(cached) = fs::read_to_string(&path) { + if let Ok(cached) = cached.parse() { + return cached; + } + } + + let output = f(tokens); + if fs::write(&path, output.to_string()).is_err() { + eprintln!("warning: cannot write to cache dir"); + } + output +} diff --git a/markup-proc-macro/src/lib.rs b/markup-proc-macro/src/lib.rs index 045c574..24562ea 100644 --- a/markup-proc-macro/src/lib.rs +++ b/markup-proc-macro/src/lib.rs @@ -2,11 +2,16 @@ extern crate proc_macro; mod ast; +mod caching; mod generate; mod parse; +use proc_macro::TokenStream; + #[proc_macro] -pub fn define(tokens: proc_macro::TokenStream) -> proc_macro::TokenStream { - let structs = syn::parse_macro_input!(tokens as parse::Many).0; - quote::quote!( #(#structs)* ).into() +pub fn define(tokens: TokenStream) -> TokenStream { + caching::cached(tokens, |tokens| { + let structs = syn::parse_macro_input!(tokens as parse::Many).0; + quote::quote!( #(#structs)* ).into() + }) } diff --git a/markup/Cargo.toml b/markup/Cargo.toml index 9865719..9511ee4 100644 --- a/markup/Cargo.toml +++ b/markup/Cargo.toml @@ -14,3 +14,6 @@ categories = ["template-engine"] [dependencies] markup-proc-macro = { path = "../markup-proc-macro", version = "0.4.0" } + +[features] +caching = ["markup-proc-macro/caching"] From a4e5034ba95eeb26c68dc3942a1936608d31cb1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Zmarz=C5=82y?= Date: Sun, 15 Sep 2019 07:28:12 +0200 Subject: [PATCH 2/2] Use separate cache dirs for different crate versions --- markup-proc-macro/Cargo.toml | 3 ++- markup-proc-macro/src/caching.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/markup-proc-macro/Cargo.toml b/markup-proc-macro/Cargo.toml index 45cc095..af288a9 100644 --- a/markup-proc-macro/Cargo.toml +++ b/markup-proc-macro/Cargo.toml @@ -18,6 +18,7 @@ quote = "1.0.2" syn = { version = "1.0.5", features = ["extra-traits", "full"] } sha2 = { version = "0.8", optional = true } dirs = { version = "2.0.2", optional = true } +version = { version = "3.0.0", optional = true } [features] -caching = ["sha2", "dirs"] +caching = ["sha2", "dirs", "version"] diff --git a/markup-proc-macro/src/caching.rs b/markup-proc-macro/src/caching.rs index d6bb4e2..22fc9d9 100644 --- a/markup-proc-macro/src/caching.rs +++ b/markup-proc-macro/src/caching.rs @@ -12,6 +12,8 @@ pub fn cached(tokens: TokenStream, f: impl FnOnce(TokenStream) -> TokenStream) - let dir = dirs::cache_dir().unwrap().join("markup-rs"); let _ = fs::create_dir(&dir); + let dir = dir.join(version::version!().to_string()); + let _ = fs::create_dir(&dir); let input = tokens.to_string(); let mut hasher = Sha256::new();