min-specialization 0.2.1

Experimental implementation of specialization
Documentation
<p align="center">
  <img src="https://raw.githubusercontent.com/yasuo-ozu/min_specialization/main/logo.png" alt="min-specialization logo" width="200">
</p>

# min-specialization [![Latest Version]][crates.io] [![Documentation]][docs.rs] [![GitHub Actions]][actions]

[Latest Version]: https://img.shields.io/crates/v/min-specialization.svg
[crates.io]: https://crates.io/crates/min-specialization
[Documentation]: https://img.shields.io/docsrs/min-specialization
[docs.rs]: https://docs.rs/min-specialization/latest/min_specialization/
[GitHub Actions]: https://github.com/yasuo-ozu/min_specialization/actions/workflows/rust.yml/badge.svg
[actions]: https://github.com/yasuo-ozu/min_specialization/actions/workflows/rust.yml

Rust's specialization feature allows you to provide a default implementation of a trait for generic types and then specialize it for specific types. This feature is currently unstable and only available on the nightly version of Rust.

This crate emulates Rust's `#[feature(min_specialization)]` unstable feature on stable Rust.

# Example

Annotate a module with `#[specialization]`. Inside it, write a trait, one
*blanket* implementation that provides the default behaviour (its specializable
methods are marked `default`), and any number of concrete implementations that
override those methods for specific types:

```rust
use min_specialization::specialization;

#[specialization]
mod inner {
    #[allow(unused)]
    trait Trait<U> {
        type Ty;
        fn number(_: U) -> Self::Ty;
    }

    impl<T, U> Trait<U> for T {
        type Ty = usize;
        default fn number(_: U) -> Self::Ty {
            0
        }
    }

    impl<U> Trait<U> for () {
        fn number(_: U) -> Self::Ty {
            1
        }
    }
}
```

# A more complex example

A blanket impl can have several specializations, including ones for borrowed
types such as `&str` (which `TypeId`-based dispatch normally forbids, since it
requires `'static`). Associated types are defined once by the blanket impl and
shared by every specialization — only methods are specialized. Dispatch happens
at run time and picks the most specific matching impl:

```rust
use min_specialization::specialization;

#[specialization]
mod describe {
    pub trait Describe {
        type Out;
        fn describe(&self) -> Self::Out;
    }

    // The blanket impl defines the associated type and the `default` method
    // used by every type that is not specialized below.
    impl<T> Describe for T {
        type Out = &'static str;
        default fn describe(&self) -> Self::Out {
            "something else"
        }
    }

    // Specializations override the method for concrete types...
    impl Describe for bool {
        fn describe(&self) -> Self::Out {
            "a boolean"
        }
    }
    impl Describe for i32 {
        fn describe(&self) -> Self::Out {
            "an integer"
        }
    }

    // ...including borrowed types.
    impl Describe for &str {
        fn describe(&self) -> Self::Out {
            "a string slice"
        }
    }
}

use describe::Describe;

assert_eq!(true.describe(), "a boolean");         // specialized
assert_eq!(7i32.describe(), "an integer");        // specialized
assert_eq!("hi".describe(), "a string slice");    // specialized (borrowed type)
assert_eq!(2.5f64.describe(), "something else");  // blanket default
```

Specialization also supports generic methods (including `const` generics),
generic associated types (GATs), trait lifetime parameters, and non-trivial
argument patterns; see `tests` for more.