split_by_discriminant
split_by_discriminant is a lightweight Rust utility for partitioning a sequence of items by the discriminant of an enum. It is especially useful when you need to gather all values of a particular variant, operate on them, and then return them to the original collection.
Primary API
split_by_discriminant
Generic function that takes:
- An iterable of items (
items) whose element typeRimplementsBorrow<T>(e.g.&T,&mut T, orT). - An iterable of discriminants (
kinds) to match against; duplicates are ignored.
Returns a [SplitByDiscriminant<T, R>] containing:
groups: a map from discriminant to aVec<R>of matching items.others: aVec<R>of items whose discriminant was not requested.
Type inference normally deduces the return type; you rarely need to annotate it explicitly.
SplitByDiscriminant struct
Provides methods:
into_parts(self) -> (HashMap<Discriminant<T>, Vec<R>>, Vec<R>)— consume the struct and obtain the groups and others.group(&mut self, id: Discriminant<T>) -> Option<&Vec<R>>— access a particular group by discriminant.
If R additionally implements BorrowMut<T>, you get a helper:
extract<U>(&mut self, id: Discriminant<T>) -> Option<Vec<&mut U>> where T: Extract<U>
This method returns mutable references to inner values of the specified type for a given discriminant. The user is responsible for implementing the Extract<U> trait on their enum type to define how to borrow out the inner value of type U.
Extract trait
Implement this to enable SplitByDiscriminant::extract in mutable contexts. Typically you match against an enum variant and return a reference to its payload.
Examples
use ;
use discriminant;
let mut data = ;
let a_disc = discriminant;
// borrow a mutable slice
let mut split: =
split_by_discriminant;
// access group and modify inner values
if let Some = split.group
if let Some = split.
You can also pass an owned iterator:
let owned = vec!;
let mut split3 = split_by_discriminant;
Or use immutable references:
let data = ;
let mut split2 = split_by_discriminant;
assert_eq!;
Supported Inputs
&mut [T]or&mut Vec<T>⇒SplitByDiscriminant<T, &mut T>&[T]or&Vec<T>⇒SplitByDiscriminant<T, &T>- Any owning iterator, e.g.
Vec<T>::into_iter()⇒R = T.
Notes
- You can precompute discriminants using
std::mem::discriminantand store them inconsts for reuse. - Items not matching any requested discriminant are preserved in
others, preserving original order.
Testing
Unit and integration-style tests live in src/tests.rs demonstrating various use cases and ensuring API correctness.
This library emphasizes ergonomic partitioning based on enum discriminants with minimal trait bounds, making it compatible with a wide variety of container and ownership patterns.