| Crates.io | disjoint_impls |
| lib.rs | disjoint_impls |
| version | 1.3.6 |
| created_at | 2023-09-23 12:39:35.044691+00 |
| updated_at | 2026-01-22 16:01:39.28149+00 |
| description | Support for mutually disjoint impls |
| homepage | |
| repository | https://github.com/mversic/disjoint_impls |
| max_upload_size | |
| id | 981215 |
| size | 402,243 |
Crate will be maintained (at least) until this idiom is allowed by the Rust compiler directly
Enables writing non-overlapping (disjoint) impls distinguished by a set of associated types.
Works for trait and inherent implementations alike (no special syntax).
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 {}
}
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> {}
}
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.