sealed 0.7.0

Macro for sealing traits and structures
Documentation
<img src="images/sealed.png" width=100 align="left">

<!-- cargo-rdme start -->

# `#[sealed]`

[<img alt="" src="https://img.shields.io/badge/docs.rs-sealed-success?style=flat-square">](https://docs.rs/sealed)
[<img alt="" src="https://img.shields.io/crates/v/sealed?style=flat-square">](https://crates.io/crates/sealed)
<img alt="MSRV 1.71.0" src="https://img.shields.io/badge/msrv-1.71.0-blue?style=flat-square">

This crate provides a convenient and simple way to implement the sealed trait pattern,
as described in the Rust API Guidelines [[1](https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed)].

```toml
[dependencies]
sealed = "0.7"
```

## Example

In the following code structs `A` and `B` implement the sealed trait `T`,
the `C` struct, which is not sealed, will error during compilation.

Examples are available in [`examples/`](examples/), you can also see a demo in [`demo/`](demo/).

```rust
#[sealed]
trait T {}

pub struct A;
#[sealed]
impl T for A {}

pub struct B;
#[sealed]
impl T for B {}

pub struct C;
impl T for C {} // compile error
```

## Details

The attribute generates a private uniquely named module when attached to a
trait definition, when attached to an `impl` block the generated code simply
implements the sealed trait for the respective type.

```rust
// #[sealed]
// trait T {}
trait T: __seal_t::Sealed {}
mod __seal_t {
    pub trait Sealed {}
}

pub struct A;

// #[sealed]
// impl T for A {}
impl T for A {}
impl __seal_t::Sealed for A {}
```

## Arguments

The expanded code may be customized with the following attribute arguments.

### `erase`

Turns on trait bounds erasure. This is useful when using the `#[sealed]`
attribute inside a function. By default, all the bounds are propagated to
the generated `Sealed` trait.

```rust
// #[sealed(erase)]
// trait Trait<T: ?Sized + Default> {}
trait Trait<T: ?Sized + Default>: __seal_trait::Sealed<T> {}
mod __seal_trait {
    pub trait Sealed<T> {}
}
```

### `pub(crate)` or `pub(in some::path)`

Allows to tune visibility of the generated sealing module (the default one
is private). This useful when the trait and its impls are defined in
different modules.

```rust
mod lets {
    pub mod attempt {
        pub mod some {
            pub mod nesting {
                #[sealed(pub(in super::super::super::super))]
                pub trait T {}
            }
        }
    }
}

pub struct A;
#[sealed]
impl lets::attempt::some::nesting::T for A {}
```

Notice, that just `pub` is disallowed as breaks the whole idea of sealing.

```rust
#[sealed(pub)] // compile error
trait T {}

pub struct A;
#[sealed]
impl T for A {}
```

<!-- cargo-rdme end -->

### Contributing

See [CONTRIBUTING.md](.github/CONTRIBUTING.md).

#### License

<sup>
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
</sup>

<br>

<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.
</sub>