maybe-impl 0.1.0

Provides support to conditionally implement one or more traits
Documentation
# Maybe Implements   ![CI][ci-badge] [![Crates.io][crates-badge]][crates-url] [![MIT licensed][mit-badge]][mit-url] 


[crates-badge]: https://img.shields.io/crates/v/maybe-impl.svg
[crates-url]: https://crates.io/crates/maybe-impl
[mit-badge]: https://img.shields.io/badge/license-MIT-blueviolet.svg
[mit-url]: https://github.com/commonsensesoftware/maybe-impl/blob/main/LICENSE
[ci-badge]: https://github.com/commonsensesoftware/maybe-impl/actions/workflows/ci.yml/badge.svg

Maybe Implements provides Rust procedural macro attributes that can be used to optionally implement traits.

## Optional Traits in Action


Technically, the provided attribute **always** implements the specified traits. It can be combined with the
existing `cfg_attr` attribute to conditionally implement one or more traits. The primary use case for such
behavior is optionally implementing `Send` and `Sync`.

First, consider that asynchronous behavior is an optional feature in your crate:

```toml
[features]
async = ["maybe-impl"]

[dependencies]
maybe-impl = { version = "0.1.0", optional = true }
```

Consider the crate has the following trait:

```rust
#[cfg_attr(feature = "async", maybe_impl::traits(Send,Sync))]

trait Foo {
    fn bar(&self);
}
```

When the crate is used with the default features, there is no change in behavior. When the `async` feature is enabled:

```bash
cargo add my-crate --features async
```

The trait is expanded to:

```rust
trait Foo: Send + Sync {
    fn bar(&self);
}
```

## Using Generics


If you define a trait with generics that requires `Send` and/or `Sync`, specifically, that will require the generic type constraint to match. [Trait aliases](https://doc.rust-lang.org/unstable-book/language-features/trait-alias.html) are currently unstable, however, you can bridge these two concepts with a _pseudo_ trait alias by defining a marker trait with a blanket implementation.

```rust
#[cfg(not(feature = "async"))]

trait Bar: Sized {}

#[cfg(not(feature = "async"))]

impl<T> Bar for T {}

#[cfg(feature = "async")]

trait Bar: Sized + Send + Sync {}

#[cfg(feature = "async")]

impl<T: Send + Sync> Bar for T {}

#[cfg_attr(feature = "async", maybe_impl::traits(Send,Sync))]

trait Foo<T: Bar> {
    fn bar(&self, bar: &T);
}
```

The default, synchronous build remains vanilla, while the asynchronous path expands to the equivalent of:

```rust
trait Foo<T: Send + Sync>: Send + Sync {
    fn bar(&self, bar: &T);
}
```

## License


This project is licensed under the [MIT license].

[MIT license]: https://github.com/commonsensesoftware/more-rs-di/blob/main/LICENSE