#rust
#Ржавчина
Вопрос:
Я написал макрос в ящике и импортировал его в основную функцию основного проекта.
Макрос зависит от:
use chrono::{Utc, Local, DateTime, Date};
В настоящее время я включаю зависимость в Cargo.toml основного проекта.
Нужно ли мне делать то же самое для всех основных проектов? Или я могу объявить зависимость в Cargo.toml ящика макросов?
//lib.rs //Mymacro
#[macro_export]
macro_rules! time {
() => {
use chrono::{Utc, Local, DateTime, Date};
let local_datetime: DateTime<Local> = Local::now();
println!("{:?}",local_datetime);
}
}
//main.rs // main project
extern crate Mymacro;
#[macro_use]
fn main() {
time!();
}
// Cargo.html
[dependencies]
chrono=""
Ответ №1:
Нужно ли мне делать то же самое для всех основных проектов? Или я могу объявить зависимость в Cargo.toml ящика макросов?
Вы можете либо (1) вызвать макрокомандой функцию в своей библиотеке, либо (2) выполнить реэкспорт chrono
(частично или полностью).
Давайте рассмотрим, что у нас есть рабочее пространство с ящиком lib
и bin
.
[workspace]
members = [
"bin",
"lib",
]
Теперь в вашем Cargo.toml
для lib
ящика, который вы бы включили в chrono
качестве зависимости, как и в противном случае.
[dependencies]
chrono = "0.4"
В то время Cargo.toml
как для bin
ящика есть только зависимость lib
.
[dependencies]
lib = { path = "../lib" }
Теперь давайте рассмотрим, что main.rs
в bin
ящике выглядит так:
use lib::time;
fn main() {
time!();
}
Он останется неизменным, независимо от того, какой вариант вы выберете.
Следующие фрагменты представляют lib.rs
.
Библиотечная функция
Если вы никогда не возвращаете какие-либо chrono
конкретные типы, это может быть проще всего. Поскольку вы полностью избегаете повторного экспорта chrono.
use chrono::{DateTime, Local};
pub fn _time() {
let local_datetime: DateTime<Local> = Local::now();
println!("{:?}", local_datetime);
}
#[macro_export]
macro_rules! time {
() => {
$crate::_time();
};
}
Если вы не хотите _time
появляться в документации вашей библиотеки, вы можете использовать #[doc(hidden)]
атрибут.
Повторный экспорт некоторых элементов
В качестве альтернативы, если вы хотите, чтобы все оставалось внутри макроса, вы можете повторно экспортировать chrono
типы, которые он использует, и добавить типы в свой макрос $crate::
.
Недостатком этого является то, что если вашему bin
ящику нужен chrono
тип, который не реэкспортируется, то это может быть «раздражением» и, следовательно bin
, должно зависеть в chrono = "0.4"
любом случае.
pub use chrono::{DateTime, Local};
#[macro_export]
macro_rules! time {
() => {
let local_datetime: $crate::DateTime<$crate::Local> = $crate::Local::now();
println!("{:?}", local_datetime);
};
}
main.rs
Если вы вместо этого это сделаете use lib::*;
, то вам, конечно, не нужно добавлять $crate::
, но лучше этого не делать use lib::*;
.
Повторный экспорт Chrono
Наконец, если вам нужны chrono
типы в вашем bin
ящике. Затем вы также можете повторно экспортировать весь chrono
ящик с pub extern crate chrono;
помощью .
Обратите внимание, что на этот раз вам нужно добавить типы в свой макрос с $crate::chrono::
помощью .
pub extern crate chrono;
#[macro_export]
macro_rules! time {
() => {
let local_datetime: $crate::chrono::DateTime<$crate::chrono::Local> =
$crate::chrono::Local::now();
println!("{:?}", local_datetime);
};
}