Will I need to do the same for all main projects? Or Can I declare the dependency in the Cargo.toml of the macro crate?
You can, by either (1) having your macro call a function in your library or (2) by re-exporting chrono (partially or completely).
Let's consider that we have a workspace, with a lib and bin crate.
[workspace]
members = [
"bin",
"lib",
]
Now in your Cargo.toml for the lib crate you'd include chrono as a dependency, like you otherwise would.
[dependencies]
chrono = "0.4"
While the Cargo.toml for the bin crate only has the dependency of lib.
[dependencies]
lib = { path = "../lib" }
Now, let's consider that main.rs in the bin crate looks like this:
use lib::time;
fn main() {
time!();
}
It will remain the same, regardless of which option you go with.
The following snippets represent lib.rs.
Library Function
If you never actually return any chrono specific types, then this might be the easiest. As you avoid re-exporting chrono completely.
use chrono::{DateTime, Local};
pub fn _time() {
let local_datetime: DateTime<Local> = Local::now();
println!("{:?}", local_datetime);
}
#[macro_export]
macro_rules! time {
() => {
$crate::_time();
};
}
If you don't want _time to appear in the documentation of your library, then you can use the #[doc(hidden)] attribute.
Re-export some items
Alternatively, if you want everything to remain within the macro, then you can re-export the chrono types it uses, and prepend the types in your macro with $crate::.
The downside to this, is that if your bin crate needs a chrono type that is not re-exported, then that can be an "annoyance" and thus bin would need to depend on chrono = "0.4" anyways.
pub use chrono::{DateTime, Local};
#[macro_export]
macro_rules! time {
() => {
let local_datetime: $crate::DateTime<$crate::Local> = $crate::Local::now();
println!("{:?}", local_datetime);
};
}
In main.rs if you instead do use lib::*;, then you'd of course not need to prepend $crate::, but it's best to avoid doing use lib::*;.
Re-export Chrono
Lastly, if you need the chrono types in you bin crate. Then you can also re-export the whole chrono crate with pub extern crate chrono;.
Note that this time, you need to prepend the types in your macro with $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);
};
}