Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macro: pub fn is not supported #15

Closed
behnam opened this issue Oct 5, 2018 · 5 comments · Fixed by #33
Closed

macro: pub fn is not supported #15

behnam opened this issue Oct 5, 2018 · 5 comments · Fixed by #33

Comments

@behnam
Copy link

behnam commented Oct 5, 2018

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
Copy link
Owner

jaemk commented Oct 5, 2018

Woops... that's an oversight!

@Rahix
Copy link
Contributor

Rahix commented Oct 22, 2018

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
Copy link

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
Copy link

kirhgoff commented Oct 31, 2018

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
Copy link
Contributor

Rahix commented Oct 31, 2018

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.

This was referenced May 29, 2020
@jaemk jaemk closed this as completed in #33 May 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants