<img src="images/sealed.png" width=100 align="left">
# `#[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 {}
```
### 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>