35 releases (stable)
Uses new Rust 2024
| new 1.3.7 | Feb 12, 2026 |
|---|---|
| 1.3.4 | Dec 4, 2025 |
| 1.3.3 | Nov 27, 2025 |
| 1.0.3 | Jun 28, 2025 |
| 0.5.0 | Nov 23, 2023 |
#6 in #disjoint
657 downloads per month
Used in staircase
250KB
6.5K
SLoC
Crate will be maintained (at least) until this idiom is allowed by the Rust compiler directly
Description
Enables writing non-overlapping (disjoint) impls distinguished by a set of associated types.
Works for trait and inherent implementations alike (no special syntax).
Trait implementations
use disjoint_impls::disjoint_impls;
pub trait Dispatch {
type Group;
}
disjoint_impls! {
pub trait Kita {}
impl<T: Dispatch<Group = u32>> Kita for T {}
impl<T: Dispatch<Group = i32>> Kita for T {}
}
Inherent implementations
use disjoint_impls::disjoint_impls;
pub trait Dispatch {
type Group;
}
struct Wrapper<T>(T);
disjoint_impls! {
impl<T: Dispatch<Group = u32>> Wrapper<T> {}
impl<T: Dispatch<Group = i32>> Wrapper<T> {}
}
Foreign(remote) traits
For traits defined outside the current crate (a.k.a. foreign or remote traits), duplicate
the trait definition inside the macro and annotate it with #[disjoint_impls(remote)].
use disjoint_impls::disjoint_impls;
// A foreign trait must be brought into scope so
// the `disjoint_impls!` macro can refer to it.
use remote_trait::ForeignKita;
pub trait Dispatch {
type Group;
}
// (orphan rule): You can define blanket impls only
// for types that are defined in the current crate
pub struct LocalType<T>(T);
disjoint_impls! {
#[disjoint_impls(remote)]
pub trait ForeignKita {}
impl<T: Dispatch<Group = u32>> ForeignKita for LocalType<T> {}
impl<T: Dispatch<Group = i32>> ForeignKita for LocalType<T> {}
}
Other, much more complex examples, can be found in tests.
Dependencies
~1.2–2MB
~36K SLoC