announce 0.1.0

Definition-side trampolines: make a definition known to proc macros in any crate
Documentation
# announce crate [![Latest Version]][crates.io] [![Documentation]][docs.rs] [![GitHub Actions]][actions] [![MSRV]][msrv]

[Latest Version]: https://img.shields.io/crates/v/announce.svg
[crates.io]: https://crates.io/crates/announce
[Documentation]: https://img.shields.io/docsrs/announce
[docs.rs]: https://docs.rs/announce/latest/announce/
[GitHub Actions]: https://github.com/yasuo-ozu/announce/actions/workflows/rust.yml/badge.svg
[actions]: https://github.com/yasuo-ozu/announce/actions/workflows/rust.yml
[MSRV]: https://img.shields.io/badge/MSRV-1.57-blue.svg
[msrv]: https://github.com/yasuo-ozu/announce/blob/main/Cargo.toml

<p align="center"><img src="https://raw.githubusercontent.com/yasuo-ozu/announce/main/logo.png" alt="announce" width="200"></p>

Make a definition visible to proc macros in any crate.

A proc macro only sees the tokens it is applied to. Put `#[announce]` on a
struct, enum, union, trait, type alias or inline `mod`, and any crate can ask for
its tokens: `#[announce]` keeps the item and emits a `macro_rules!` with the
item's name, and calling that macro passes the definition to a callback macro.

```rust
#[announce::announce]
pub trait Greet { fn hi(&self) -> &'static str; }

macro_rules! show {
    ([$($list:tt)*] $($key:ident)::+ ! => [$($meta:tt)*] { $($item:tt)* } $($rest:tt)*) => {
        const SHOWN: &str = stringify!($($item)*);
    };
}
Greet! { [Greet!, show!] }
assert!(SHOWN.contains("trait Greet"));
```

From another crate the call reads `path::to::Greet! { [path::to::Greet!, show!] REST }`.
The callback receives the definition, and `REST` unchanged:

```text
show! {
    [show!]
    path::to::Greet! => [META] { pub trait Greet { fn hi(&self) -> &'static str; } }
    REST
}
```

`META` lists what the definer attached (checks, `meta` entries). Callers and
callbacks need no dependency on announce.

For a struct, enum or union you write yourself, derive it instead. The derive
also implements the [`Announce`](https://docs.rs/announce/latest/announce/trait.Announce.html)
trait, and takes the same options in a helper attribute `#[announce(..)]`:

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

## Calling a trampoline

One callback can take many definitions. The list names the trampolines, then
the callback, which runs once. A long chain may need a higher `recursion_limit`
([details](https://docs.rs/announce/latest/announce/attr.announce.html#size-and-recursion)).

```text
path::Item! { [path::Item!, other::Def!, cb!] REST }
```

## Features

- Works in any position: item, statement, expression, type, pattern.
- Evaluates `#[cfg]` in the defining crate; `crate::` paths keep pointing there.
- Leaves docs out of the item the callback receives (`docs = true` keeps them).
- Checks at the definition, which can own attributes of their own inside the item:
  [`#[announce(my_lib::check)]`]https://docs.rs/announce/latest/announce/attr.announce.html#checks-and-attributes-of-your-own.
- Metadata for consumers: `#[announce(meta = my_lib::info(k = v))]`.
- Types that are relative to the defining crate: [`repeater`]https://docs.rs/announce/latest/announce/attr.announce.html#type-context.
- Transformers chosen by the caller, such as
  [`signature_only!`]https://docs.rs/announce/latest/announce/macro.signature_only.html.
- A derive or attribute may own the name: rename the trampoline with `macro_name`.

All options of `#[announce(..)]` are in the
[API docs](https://docs.rs/announce/latest/announce/attr.announce.html).

## Crates

| crate | use it to |
|---|---|
| [`announce`]https://docs.rs/announce | everything below |
| [`announce-std`]https://docs.rs/announce-std | announce std/core traits (`announce_std::iter::Iterator!`) |

In `announce`:

- `#[announce]`, `#[derive(Announce)]` and the trait `Announce` define announced items.
- [`announce::helper`]https://docs.rs/announce/latest/announce/helper/index.html
  writes callbacks and checks, starts chains and redirects derives.
- [`announce::machinery`]https://docs.rs/announce/latest/announce/machinery/index.html
  announces items that your own proc macro builds.

`announce-core` and `announce-macros` are internal; depend on `announce`.
Minimum Rust version: 1.57.

## Performance

Traits with S methods each, K of them passed to one callback; rustc nightly,
dev profile. Lines: color = S (darker is larger), solid = announced or one
chain, dashed = plain or K separate calls; both axes logarithmic. Details and
how to run it: `bench/`.

<img src="https://raw.githubusercontent.com/yasuo-ozu/announce/main/bench/plots/defining-rmeta.svg" alt="Defining crate: .rmeta size against K" width="49%"> <img src="https://raw.githubusercontent.com/yasuo-ozu/announce/main/bench/plots/defining-time.svg" alt="Defining crate: rebuild time against K" width="49%">
<img src="https://raw.githubusercontent.com/yasuo-ozu/announce/main/bench/plots/calling-rmeta.svg" alt="Calling crate: .rmeta size against K" width="49%"> <img src="https://raw.githubusercontent.com/yasuo-ozu/announce/main/bench/plots/calling-time.svg" alt="Calling crate: rebuild time against K" width="49%">

- The cost is metadata of the defining crate: about 6 KiB per definition plus
  copies of the item (one copy for items above about 21 trait methods). Doc
  comments are not recorded.
- Executables are unaffected, and calling crates stay small (12–60 KiB of
  `.rmeta` at K = 96).
- `[profile.dev.build-override] opt-level = 3` in your workspace builds the
  proc macros optimized: 1,117 ms becomes 763 ms at S = 200, K = 96.

## Related crates

- **[macro_magic]https://crates.io/crates/macro_magic** has the same core idea.
  announce adds continuation lists, definition-side cfg evaluation and checks,
  and type context handling.
- **[reify_types]https://crates.io/crates/reify_types** makes a definition
  available when compiled code *runs*. announce delivers it at *compile time*.