17 releases (10 stable)
new 2.1.0 | Feb 11, 2025 |
---|---|
2.0.0 | Feb 9, 2025 |
1.3.4 | Feb 9, 2025 |
0.11.0 | Feb 6, 2025 |
0.9.2 | Feb 6, 2025 |
#186 in Rust patterns
1,914 downloads per month
310KB
1K
SLoC
AnyOf : a versatile type for Rust
This project implements a flexible Algebraic Data Type : AnyOf
.
AnyOf
is an optional sum of product of two types,
which enables clear and safe data representations in functional and type-driven programming.
Overview
At the core of the project is the AnyOf
enum, a general-purpose algebraic type,
alongside additional types as EitherOf
and BothOf
.
These abstractions allow to express dynamic states, optional values, and branching logic in a natural and explicit manner.
Key Types
-
AnyOf<L, R>
- A flexible type that represents four possible states:
Neither
: No value is present.Either
:Left
: Only the left value is present.Right
: Only the right value is present.
Both
: Both values are present.
- It combines variants in the following way:
AnyOf<L, R> = Neither | EitherOf<L, R> | BothOf<L, R>
- Its cases are:
AnyOf(L, R) = Neither | Left(L) | Right(R) | BothOf{left: L, right: R}
- This type can also be viewed as a product of two optional types:
Cases :AnyOf<L, R>::any() -> (Option<L>, Option<R>)
Neither.any()
returns(None, None)
Left(L).any()
returns(Some(L), None)
Right(R).any()
returns(None, Some(R))
Both(L, R).any()
returns(Some(L), Some(R))
- A flexible type that represents four possible states:
-
EitherOf<L, R>
- A simple sum type representing one of two values.
- Variants:
Left(L)
Right(R)
- Ideal for binary decision-making.
- Implements
any()
too :Left(L).any()
returns(Some(L), None)
Right(R).any()
returns(None, Some(R))
- It is the type :
EitherOf<L, R> = Left(L) | Right(R)
-
BothOf<L, R>
- A product type that pairs two values,
left
andright
, of potentially different types. - Implements
any()
too :BothOf{ left: L, right: R }.any()
returns(Some(L), Some(R))
- It is the type:
BothOf<L, R> = {left: L, right: R}
- It can be transformed into a tuple with:
into_couple(self) -> Couple<L, R>
, - And can be transformed from a tuple with:
from_couple(Couple<L, R>) -> Self
,
- A product type that pairs two values,
-
Enhanced Type Composition
- A
Couple<T, U>
is a(T, U)
, - A
Pair<T>
is aCouple<T, T>
, - An
Any<T, U>
is aCouple<Option<T>, Option<U>>
, - Complex types like
AnyOf4
,AnyOf8
, andAnyOf16
are implemented for handling larger, structured combinations via nestedAnyOf
structures. - The
LeftOrRight
trait :- Provides the methods
is_right()
,is_left()
,any()
,left()
andright()
. - Implemented by
AnyOf
,EitherOf
andBothOf
, - Can be implemented by a custom type.
- Provides the methods
- Other useful traits :
Unwrap<L, R>
,Swap<L, R>
andMap<L, R>
.
- A
Features and Utilities
-
Methods inspired by Rust's
Option
andResult
types:- Creation utilities:
new
,new_left
,new_both
, etc. - State checks:
is_neither
,is_left
,is_both
, etc. - Transformations:
map_left
,map_right
,swap
, etc. - Unwrapping:
unwrap_left
,unwrap_right
,unwrap_both
.
- Creation utilities:
-
Flexible combinations:
- Operators :
+
to combineAnyOf
values, or,-
to filterAnyOf
values, or,!
to swapAnyOf
,EitherOf
andBothOf
values,>>
to mapAnyOf
,EitherOf
andBothOf
values,
- Default value handling and state manipulation methods.
- Operators :
Use Cases
AnyOf
and its related types simplify dynamic state management and are well-suited for:
- Branching logic in functional programming.
- Handling optional or partial data.
- Implementing explicit and exhaustive handling of all potential states.
- Minimizing boilerplate for complex decision-making.
Motivation
The project aims to enrich Rust's type system with expressive and flexible types
for representing data combinations and states.
It is inspired by the Haskel's Either
type.
- Unlike the Rust's
Result
type, the typesAnyOf
,EitherOf
orLeftOrRight
have not an "error" semantic, they are general purpose, LeftOrRight<L, R>::any()
can be represented by a(Option<L>, Option<R>)
which is a product of two optional types, but the two types has not the same composition conciseness :AnyOf<AnyOf<LL, LR>, AnyOf<RL, RR>> vs (Option<(Option<LL>, Option<LR>)>, Option<(Option<RL>, Option<RR>)>) AnyOf<AnyOf<AnyOf<LLL, LLR>, AnyOf<LRL, LRR>>, AnyOf<AnyOf<RLL, RLR>, AnyOf<RRL, RRR>>> vs (Option<(Option<(Option<LLL>, Option<LLR>)>, Option<(Option<LRL>, Option<LRR>)>)>, Option<(Option<(Option<RLL>, Option<RLR>)>, Option<(Option<RRL>, Option<RRR>)>)>)
Status
The library may evolve following semantic versioning, so the API will be stable in a given major version.
License
© 2025 Sébastien Geldreich
Distributed under the MIT License.