Exporting templates

But now suppose that you want to expose your template, so that people can use it from any crate.

To do this, you use export before the name of your macro:

pub trait HelloWorld {
    fn greet();
}

derive_deftly::define_derive_deftly! {
    /// Derives `HelloWorld`, providing `greet`
    export HelloWorld:
    impl $crate::HelloWorld for $ttype {
        fn greet() {
            println!("Greetings from {}", stringify!($ttype));
        }
    }
}
fn main() {}

Declaring our template as export HelloWorld in this way is equivalent to marking derive_deftly_template_HelloWorld with #[macro_export]. Doing this puts the template into the root of the crate. You can make the template visible elsewhere using pub use.

Note that this time, we've defined HelloWorld as a trait, and we've changed our template to refer to that trait as $crate::HelloWorld. The $crate syntax will expand to the name of the crate in which our template was defined, so that when later we expand this template in a different crate, it will find the right trait. (Otherwise, it would fail if the HelloWorld trait were not in scope.)

We've also added a doc comment, which will appear in the public API documentation for our crate.

Additionally, we need to re-export derive_deftly from our crate, so that when our template is applied to user types, a compatible derive-deftly driver is used. And we should also invoke derive_deftly::template_export_semver_check once, somewhere in our crate: this will tells us about any implications for your crate's semver, when you change your Cargo.toml to upgrade the derive-deftly crate.

// At the root of our crate:

#[doc(hidden)]
pub use derive_deftly;

// Use the current version of derive_deftly here:
derive_deftly::template_export_semver_check!("0.11.0");

Now, when somebody wants to use our template from a different crate, they can do it like this:

// Let's pretend our crate is called hello_world.
use hello_world::{
    // This is the trait we defined...
    HelloWorld,
    // This is the macro that makes our template work.
    // (We might come up with a better syntax for this later).
    derive_deftly_template_HelloWorld
};
use derive_deftly::Deftly;

#[derive(Deftly)]
#[derive_deftly(HelloWorld)]
struct TheirStructure {
    // ...
}

Note that exporting a template to other crates with export doesn't affect its visibility within your crate. You may still need #[macro_use].

What's next

Now that we've explained how to expose a template, it's time to learn about more features from derive-deftly. In the next session, we'll start working on a Clone example, and we'll learn how to work with structs, enums, fields, variants, and more.