Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use a macro from inside its own crate? [duplicate]

Tags:

rust

I'm sure this is trivial to do, but I can't seem to make it work.

I've looked at http://doc.rust-lang.org/book/advanced-macros.html#scoping-and-macro-import/export, and I appreciate, that in general, the way to use macros is to define them using:

#[macro_export]
macro_rules! background(($token:expr) => (($token >> (32 + 8)) & $crate::graphics::mask::Color));

...and then import them into another context that uses them using:

#[macro_use]
extern crate terminal;
...

However, I what I want to do is use the macros from within the crate where they are defined.

If my file structure is:

- lib.rs
- macros.rs
- foo
- foo/mod.rs
- foo/junk.rs

How do I use the macros in macros.rs from junk.rs?

I've tried various combinations of #[macro_use] mod macros, etc. with no luck. The documentation suggests that if a macro is defined in some scope, then it is available in all child modules... does that mean I have to define my macros in lib.rs?

like image 575
Doug Avatar asked Mar 16 '15 02:03

Doug


2 Answers

The accepted answer is correct, but for anyone else who finds this question in the future, I'd like to add that the order in which modules are loaded is important.

For example, in this sequence:

pub mod terminal;
pub mod terminals;
pub mod graphics;

#[macro_use]
mod macros;

If terminal uses a macro from macros, it will not work; the #[macro_use] must occur above any other module that uses the macro:

#[macro_use]
mod macros;

pub mod terminal;
pub mod terminals;
pub mod graphics;
like image 129
Doug Avatar answered Dec 20 '22 00:12

Doug


You need to mark your macro with #[macro_export] and then mark the module with #[macro_use]:

#[macro_use]
mod macros {
    #[macro_export]
    macro_rules! my_macro(() => (42));
}

pub mod foo {
    pub mod junk {
        pub fn usage() -> u8 {
            my_macro!()
        }
    }
}

fn main() {
    println!("{:?}", foo::junk::usage());
}

Technically, you only need to use #[macro_export] if you want the macro to be available to users of your crate.

(Playground link)

like image 24
Shepmaster Avatar answered Dec 19 '22 23:12

Shepmaster