jaemk / cached

Rust cache structures and easy function memoization
MIT License
1.58k stars 95 forks source link

macro: `pub fn` is not supported #15

Closed behnam closed 4 years ago

behnam commented 6 years ago

The macro doesn't let me assign privacy to the function.

error: no rules expected the token `pub`
  --> src/...
   |
24 |         pub fn get(a_keyword: &str) -> Option<Self> = {
   |         ^^^
jaemk commented 6 years ago

Woops... that's an oversight!

Rahix commented 6 years ago

The Rust API Guidelines calls this C-MACRO-VIS.

Another point from that checklist that applies here is C-MACRO-ATTR

To fix both, use something like this:

macro_rules! fn_macro {
    // Allow `fn foo()`
    ($(#[$attr:meta])* fn $name:ident($arg:ident: $ty:ty) $fun:block) => {
        fn_macro!{
            internal $(#[$attr])* [] fn $name($arg: $ty) $fun
        }
    };
    // Allow `pub(...) fn foo()`
    ($(#[$attr:meta])* pub($($vis:tt)+) fn $name:ident($arg:ident: $ty:ty) $fun:block) => {
        fn_macro!{
            internal $(#[$attr])* [pub($($vis)+)] fn $name($arg: $ty) $fun
        }
    };
    // Allow `pub fn foo()`
    ($(#[$attr:meta])* pub fn $name:ident($arg:ident: $ty:ty) $fun:block) => {
        fn_macro!{
            internal $(#[$attr])* [pub] fn $name($arg: $ty) $fun
        }
    };
    (internal $(#[$attr:meta])* [$($vis:tt)*] fn $name:ident($arg:ident: $ty:ty) $fun:block) => {
        $(#[$attr])*
        $($vis)* fn $name($arg: $ty) $fun
    };
}

fn_macro!{
    #[cfg(debug_assertions)]
    pub(crate) fn foo(bar: i32) {
        println!("{}", bar);
    }
}

fn main() {
    foo(42);
}
kirhgoff commented 6 years ago

Any chance to have it working out of the box? I also stuck with that issue, cannot use cached. The only solution I see now is to create mirroring function which will be public and will call to internal cached.

kirhgoff commented 6 years ago

But there is another issue which prevents me to do that:

error: no rules expected the token `&`
  --> locale_loader/mod.rs:73:29
   |
73 |         fn translate_cached(&'a self, locale: &str, key: &str) -> String {

I am trying to cache the structure method

Rahix commented 6 years ago

To cache a structure method you have to use a workaround like this.

The reason is that the cached macros expand to two items instead of just one which prevents them being used in an impl block.