split_by_discriminant
split_by_discriminant is a lightweight Rust utility for partitioning a sequence of items by the discriminant of an enum.
It provides two closely‑related helpers:
split_by_discriminant– the simple grouping operation.map_by_discriminant– a more flexible variant that applies separate mapping closures to matched and unmatched items, allowing you to change the output types on the fly.
Both are helpful 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.
map_by_discriminant
A more flexible variant of split_by_discriminant that accepts two mapping closures.
The first closure is applied to items whose discriminant is requested, and the second
closure handles all others. This allows the types of grouped elements and the
"others" bucket to differ, and lets you perform on-the-fly transformations during
partitioning. The semantics and borrow rules are otherwise identical to
split_by_discriminant.
The signature is:
The README examples below demonstrate the simplest usage with split_by_discriminant;
see the crate docs for a map_by_discriminant example, and the section
immediately following the examples shows a basic map_by_discriminant use case.
SplitByDiscriminant struct
Provides methods:
into_parts(self) -> (Map<Discriminant<T>, Vec<R>>, Vec<R>)— consume the struct and obtain the groups and others.
The concrete map type isHashMapby default; enabling theindexmapfeature switches toIndexMap/IndexSetinstead.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!;
You can also call [map_by_discriminant] when you need to transform the
matched and unmatched items during partitioning. The following example
converts each element to a String with a different prefix depending on
whether it was requested.
use map_by_discriminant;
use discriminant;
let data = ;
let a_disc = discriminant;
let b_disc = discriminant;
let split = map_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.