# Introduction: Using derive-deftly for easy derive macros.

**derive-deftly** is a Rust package
that you can use to define your own `derive` macros
without having to write low-level procedural macros.

The syntax is easy to learn,
but powerful enough to implement macros of
[significant](https://gitlab.torproject.org/nickm/build-deftly)
[complexity](https://gitlab.torproject.org/nickm/serde-deftly).

Here's a simple example,
to help you get a feel for the system.

## Example: deriving field accessor functions

Suppose you want to add accessor functions
for the fields in your `struct`.
You *could* do it by hand, like this:

```rust
struct MyStruct {
   a: Vec<u8>,
   b: (u32, u32),
   c: Option<u16>,
   d: (u32, u32),
   // (more fields here ...)
}
impl MyStruct {
    fn get_a(&self) -> &Vec<u8> {
        &self.a
    }
    fn get_b(&self) -> &(u32, u32) {
        &self.b
    }
    fn get_c(&self) -> &Option<u16> {
        &self.c
    }
    fn get_d(&self) -> &(u32, u32) {
        &self.b
    }
    // (more accessors here...)
}
```

But this is time consuming,
and potentially error-prone.
(Did you see the copy-paste error in `get_d`?)
If you had to define a large number of accessors like this,
or do it for a bunch of types, you might want an easier way.

(Of course, in this case, you could use an
[existing crate](https://crates.io/crates/derive-getters).
But let's suppose that there was no crate meeting your needs,
and you had to build your own.)

Here's how you could define and use
a derive-deftly template to save some time and risk.

```rust
use derive_deftly::{define_derive_deftly, Deftly};

// Defines the template
define_derive_deftly! {
    Accessors:
    // Here, $ttype will expand to the toplevel type; in this case,
    // "MyStruct".
    impl $ttype {
        // This $( ... ) block will be repeated: in this case, once per field.
        $(
            // Here we define a "get_" function: In this definition,
            // $ftype is the type of the field,
            // $fname is the name of the field,
            // and $<...> denotes token pasting.
            fn $<get_ $fname>(&self) -> &$ftype {
                &self.$fname
            }
        )
    }
}

// Applies the template to your struct
#[derive(Deftly)]
#[derive_deftly(Accessors)]
struct MyStruct {
   a: Vec<u8>,
   b: (u32, u32),
   c: Option<u16>,
   d: (u32, u32),
   // (more fields here...)
}
```


> Note 1:
>
> This example is deliberately simplified for readability.
> As written here, it only works for `struct`s
> with no generic parameters.
> Later on, we'll learn how to write templates that work
> to `enum`s, generic types, and more.

> Note 2:
>
> Some of the accessors above aren't the ones you'd write yourself
> in idiomatic Rust:
> You'd probably want to return `&str` instead of `&String`,
> and `&[u8]` instead of `&Vec<u8>`.
>
> Once again, we'll be able to do this more idiomatically
> once we're more familiar with `derive-deftly`.

## What, exactly, can derive-deftly do?

The `derive-deftly` crate helps you do a lot of neat stuff:

* You can define sophisticated _templates_ that apply,
  like `derive()` macros,
  to structs, enums, and unions.
* You can _apply_ your templates to your own structs, enums, and unions.
* You can _export_ your templates for use by other crates.
* Your templates can _define_ new types, functions, methods, and variables:
  any kind of item that Rust allows.
* Within your templates, you can look at _nearly everything_ about
  the input type: fields, variants, attributes, types, and so on.
* Your templates can use _complex control structure_ to
  define configurable behavior or special cases.


Still, there are a number of things that derive-deftly cannot do,
or cannot do yet:

* You can't apply a `derive-deftly` template to anything
  besides a struct, enum, or union.
  For example, you can't apply it to a `fn` declaration
  or an `impl` block.
* Like a `derive` macro,
  a `derive-deftly` template cannot change the type it's applied to:
  You can define a _new_ type,
  but you can't change the definition of the original type.
* The `derive-deftly` template language, though powerful,
  does not attempt to be a general-purpose
  programming language.
  There will always be some problems better solved
  through procedural macros,
  or through changes to the Rust language.
* Because of limitations in the Rust macro system,
  `derive-deftly` templates have to be applied using the
  syntax above.
  (That is, in the example above,
  you need to say `#[derive(Deftly)]` and
  `#[derive_deftly(Accessors)]`.
  You can't define a macro that delivers
  `#[derive(Accessors)]` directly.

## About this book

In the rest of this book,
we'll explain how to use derive-deftly in detail.
We'll try to explain each of its features,
and how to use it to make correct,
reliable templates that handle a broad range of situations.

## Other resources

There are other resources on derive-deftly:

* The [Reference] tries to provide is a terse but complete
  (and farily rigorous)
  guide to derive-deftly's behavior and features.
* The [rustdoc] describes the exposed members of the `derive-deftly` crate,
  along with other useful information.


[Reference]: https://docs.rs/derive-deftly/latest/derive_deftly/doc_reference/index.html
[rustdoc]: https://docs.rs/derive-deftly/latest/derive_deftly/
