2

I have the following structure:

enter image description here

Inside queues.rs I have a #[macro_export],

#[macro_export]
macro_rules! queue {...}

but I am not sure how to import it in lib.rs.

What I have looks like this:

use crate::utils::queues::*;

// use it here
let mut service_queue: Queue<isize> = queue![];

This throws an error

error: cannot find macro `queue` in this scope
  --> src/broker.rs:54:51
   |
54 |             let mut service_queue: Queue<isize> = queue![];
   |                                                   ^^^^^
   |
   = note: consider importing this macro:
           crate::queue
   = help: have you added the `#[macro_use]` on the module/import?

What is the correct way to type #[macro_use] here, and import my custom macros from utils?

FujiApple
  • 796
  • 5
  • 16
dearn44
  • 3,198
  • 4
  • 30
  • 63
  • 1
    It's hard to say without source code, but putting `#[macro_use]` on the `mod queues` item should do it. You can't use `extern crate` here because `queues` is a module; not a crate. – smitop Mar 17 '22 at 00:11
  • @Smitop I hopefully made the question clearer now, let me know if it still doesn't make sense – dearn44 Mar 17 '22 at 00:35

1 Answers1

2

You can use the queue! macro from lib.rs using the #[macro_use] attribute (playground):

#[macro_use]
mod utils {
    #[macro_use]
    mod queues {
        macro_rules! queue {
            () => { vec![] };
        }
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = queue![];
}

In your existing code you are using #[macro_export] which means it is declared in the crate root scope and not in the utils::queues module. In your error message you can see the compile is suggesting to consider importing this macro: crate::queue.

To access it in this case (playground):

mod utils {
    mod queues {
        #[macro_export]
        macro_rules! queue {
            () => { vec![] };
        }
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = queue![];
}

Note that in either case the use crate::utils::queues::*; statement does not help, in fact you'll get an unused_imports warning (unless you happen to have other items declared in that module).

There is also this trick (playground):

pub mod utils {
    pub mod queues {
        macro_rules! queue {
            () => { vec![] };
        }
        pub(crate) use queue;
    }
}

pub fn foo() {
    let _service_queue: Vec<isize> = crate::utils::queues::queue![];
}

Aside: if you plan to use the macro in other crates and you wish to retain the module hierarchy (i.e. access from my_crate::utils::queues::queue! from my_other_crate) there is a (convoluted) way to do that.

FujiApple
  • 796
  • 5
  • 16
  • I understand your last suggestion. I have no idea what the first two are though. Are you redefining my `queues` macro inside `lib.rs`? It's already created inside `utils::queues` I just want to import it somehow and use it. – dearn44 Mar 17 '22 at 14:39
  • 1
    @dearn44 no, the macro is still defined in the `utils::queues` module and imported in the root module, I just used Rust syntax for defining nested modules in a single source file (see [here](https://doc.rust-lang.org/book/ch07-05-separating-modules-into-different-files.html)) rather than separate files. The approaches shown will work if you spit the modules into separate files, give it a try. – FujiApple Mar 18 '22 at 02:59
  • I seen what you mean now. – dearn44 Mar 18 '22 at 18:02