2014-09-18 1 views
1

Я пытаюсь написать некоторые вспомогательные макросы для отладки. Таким образом, создать ящик для хранения всех из них, и сослался на обрешетке извне с помощью фазы (плагин):Как вы относитесь к функциям в ящике из экспортированного макроса ящика в ржавчине?

#[cfg(test)] 
#[phase(plugin)] 
extern crate debugging; 

Это успешно экспортирует макросы в клеть.

Однако для некоторых из этих инструментов, которые я хотел бы вызывать функции из ящика, например:

#[macro_export] 
macro_rules! trace(
    {$($arg:tt)*} => { 
    { 
     extern crate debug; 
     let s = ::macros::logger(); // <---- This! 
     let _ = s.write_line(format_args!(::std::fmt::format, $($arg)*).as_slice()); 
    } 
    }; 
) 

Используя глобальное пространство имен, то есть. :: macros :: logger работает, если макрос помещается в macros.rs и импортируется из корня корзины ящика.

Однако то, что я пытаюсь достичь здесь, это то же самое, когда макрос должен вызывать вызов из своего собственного ящика.

Если макрос правильно расширен, я считаю:

let s = ::crate_name::logger(); 

Был бы способ сделать это, но обрешетка с помощью макроса не может относиться к себе по имени, таким образом. Это приводит к ошибкам, как:

src/macros.rs:52:15: 52:20 error: failed to resolve. Maybe a missing `extern crate debugging`? 
src/macros.rs:52  let s = ::debugging::logger(); 
           ^~~~~ 
src/macros.rs:49:1: 56:2 note: in expansion of trace! 
src/file.rs:26:11: 26:29 note: expansion site 

... и, наконец, просто так, что мы совершенно ясно, о том, что я пытаюсь сделать:

crate debugging: 
    lib.rs 
    fn logger() 
    macros.rs 
    macro_rules! trace(...) // <--- Trying to figure out what to put here... 

crate foo: 
    lib.rs 
    #[phase(plugin)] extern crate debugging; 
    fn test_thing() { 
     trace!("{}", ...); // <--- So debugging::logger() is invoked here 
    } 

Итак, есть ли какой-нибудь способ сделать это из макрос?

ответ

2

На данный момент правильная вещь - использовать абсолютный путь, подобный этому, а затем сделать несколько реэкспортов в исходном ящике, чтобы путь разрешался.

I.e. в lib.rs поставил

mod debugging { 
    pub use logger; 
} 

, который реэкспорт функцию верхнего уровня, как loggerdebugging::logger. Проделана работа, которая делает этот эффект, например. $crate, который расширяется до названия ящика, из которого пришло макрос (при использовании извне), или ничего (при использовании внутри); это не обязательно окончательный дизайн, но он улучшается.

0

Для всех, кто находит это, стоит отметить, что вы не можете использовать его из ящика с фазовым плагином. Чтобы импортировать символы локально (в соответствии с принятым ответом), что вам нужно сделать это:

#[cfg(test)] 
mod debug { 
    #[phase(plugin)] 
    extern crate debugging; 
    extern crate debugging; 
    pub use self::debugging::debug; 
} 

Обратите внимание на двойной ехЬегп отладки клети, потому что, как правило, вы не хотите экспортировать модуль расширения синтаксиса как часть код.