<commit_before># Procedural Macros (and custom Derive)

As you've seen throughout the rest of the book, Rust provides a mechanism
called "derive" that lets you implement traits easily. For example,

```rust
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}
```

is a lot simpler than

```rust
struct Point {
    x: i32,
    y: i32,
}

use std::fmt;

impl fmt::Debug for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y)
    }
}
```

Rust includes several traits that you can derive, but it also lets you define
your own. We can accomplish this task through a feature of Rust called
"procedural macros." Eventually, procedural macros will allow for all sorts of
advanced metaprogramming in Rust, but today, they're only for custom derive.

Let's build a very simple trait, and derive it with custom derive.

## Hello World

So the first thing we need to do is start a new crate for our project.

```bash
$ cargo new --bin hello-world
```

All we want is to be able to call `hello_world()` on a derived type. Something
like this:

```rust,ignore
#[derive(HelloWorld)]
struct Pancakes;

fn main() {
    Pancakes::hello_world();
}
```

With some kind of nice output, like `Hello, World! My name is Pancakes.`. 

Let's go ahead and write up what we think our macro will look like from a user
perspective. In `src/main.rs` we write:

```rust,ignore
#[macro_use]
extern crate hello_world_derive;

trait HelloWorld {
    fn hello_world();
}

#[derive(HelloWorld)]
struct FrenchToast;

#[derive(HelloWorld)]
struct Waffles;

fn main() {
    FrenchToast::hello_world();
    Waffles::hello_world();
}
```

Great. So now we just need to actually write the procedural macro. At the
moment, procedural macros need to be in their own crate. Eventually, this
restriction may be lifted, but for now, it's required. As such, there's a
convention; for a crate named `foo`, a custom derive procedural macro is called
`foo-derive`. Let's start a new crate called `hello-world-derive` inside our
`hello-world` project.

```bash
$ cargo new hello-world-derive
```

To make sure that our `hello-world` crate is able to find this new crate we've
created, we'll add it to our toml:

```toml
[dependencies]
hello-world-derive = { path = "hello-world-derive" }
```

As for our the source of our `hello-world-derive` crate, here's an example:

```rust,ignore
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;<commit_msg>Rollup merge of #39840 - DaseinPhaos:patch-2, r=frewsxcv<commit_after># Procedural Macros (and custom Derive)

As you've seen throughout the rest of the book, Rust provides a mechanism
called "derive" that lets you implement traits easily. For example,

```rust
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}
```

is a lot simpler than

```rust
struct Point {
    x: i32,
    y: i32,
}

use std::fmt;

impl fmt::Debug for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Point {{ x: {}, y: {} }}", self.x, self.y)
    }
}
```

Rust includes several traits that you can derive, but it also lets you define
your own. We can accomplish this task through a feature of Rust called
"procedural macros." Eventually, procedural macros will allow for all sorts of
advanced metaprogramming in Rust, but today, they're only for custom derive.

Let's build a very simple trait, and derive it with custom derive.

## Hello World

So the first thing we need to do is start a new crate for our project.

```bash
$ cargo new --bin hello-world
```

All we want is to be able to call `hello_world()` on a derived type. Something
like this:

```rust,ignore
#[derive(HelloWorld)]
struct Pancakes;

fn main() {
    Pancakes::hello_world();
}
```

With some kind of nice output, like `Hello, World! My name is Pancakes.`. 

Let's go ahead and write up what we think our macro will look like from a user
perspective. In `src/main.rs` we write:

```rust,ignore
#[macro_use]
extern crate hello_world_derive;

trait HelloWorld {
    fn hello_world();
}

#[derive(HelloWorld)]
struct FrenchToast;

#[derive(HelloWorld)]
struct Waffles;

fn main() {
    FrenchToast::hello_world();
    Waffles::hello_world();
}
```

Great. So now we just need to actually write the procedural macro. At the
moment, procedural macros need to be in their own crate. Eventually, this
restriction may be lifted, but for now, it's required. As such, there's a
convention; for a crate named `foo`, a custom derive procedural macro is called
`foo-derive`. Let's start a new crate called `hello-world-derive` inside our
`hello-world` project.

```bash
$ cargo new hello-world-derive
```

To make sure that our `hello-world` crate is able to find this new crate we've
created, we'll add it to our toml:

```toml
[dependencies]
hello-world-derive = { path = "hello-world-derive" }
```

As for the source of our `hello-world-derive` crate, here's an example:

```rust,ignore
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;

use proc_macro::TokenStream;
{'fraction_non_alphanumeric': 0.10887017818680243, 'fraction_numerical': 0.004307812805952614, 'mean_word_length': 4.118236472945892, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5200940', 'n_tokens_mistral': 1682, 'n_tokens_neox': 1591, 'n_words': 701}