Crates.io | maybe-impl |
lib.rs | maybe-impl |
version | 0.1.0 |
source | src |
created_at | 2024-01-10 18:19:01.263606 |
updated_at | 2024-01-10 18:19:01.263606 |
description | Provides support to conditionally implement one or more traits |
homepage | |
repository | https://github.com/commonsensesoftware/maybe-impl |
max_upload_size | |
id | 1095478 |
size | 17,500 |
Maybe Implements provides Rust procedural macro attributes that can be used to optionally implement traits.
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:
[features]
async = ["maybe-impl"]
[dependencies]
maybe-impl = { version = "0.1.0", optional = true }
Consider the crate has the following trait:
#[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:
cargo add my-crate --features async
The trait is expanded to:
trait Foo: Send + Sync {
fn bar(&self);
}
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 are currently unstable, however, you can bridge these two concepts with a pseudo trait alias by defining a marker trait with a blanket implementation.
#[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:
trait Foo<T: Send + Sync>: Send + Sync {
fn bar(&self, bar: &T);
}
This project is licensed under the MIT license.