Groups of optional values where at least one value is present
Motivation
Sometimes applications need to ensure at least one value is present, while also allowing
multiple values of distinct types. A common pattern in this case, is to track multiple Option
values and require at least one contains a value:
/// Represent distinct optional values for a couple of types:
let good_value = NameId ;
assert!;
let bad_value = NameId ;
assert!;
Overview
This crate provides types to represent this pattern:
Sometimes applications need to represent 1 or more values which may have distinct types. This
is where someval comes in to "make illegal states unrepresentable" for this pattern.
A "someval" is a type similar to a set of Option values except it guarantees at type-checking
time that at least one value is always present at runtime.
The "someval" types
The "someval" types in this crate follow common structure, varying in the number of generics
they support. They are all named SomeN with the suffix N indicating how many distinct values
are possible, e.g. [Some2], [Some3], etc… So [Some2] is generic over two types: Some2<A, B>,
while [Some3] is generic over three: Some3<A, B, C>, etc…
Each "someval" type is an enum. Both type parameters and enum variants use the uppercase English alphabet as placeholders, e.g.:
use Some2;
type NameId = ;
let nid = A;
There is an enum variant for every combination of values present:
use Some3;
type Triple = ;
let val = AC;
Constructing "somevals"
Values can be constructed with the enum variants:
use Some2;
type NameId = ;
let nid1 = A;
let nid2 = B;
let nid3 = AB;
A value with all types present can be converted from a tuple of values via From:
# use Some2;
# type NameId = ;
# let nid3 = AB;
let nid4 = from;
assert_eq!;
A value can by fallibly converted from a tuple of Option values via TryFrom:
# use Some2;
# type NameId = ;
let res1 = try_from;
assert!;
let res2 = try_from;
assert!;
A "someval" like [Some2] can always be converted to a tuple of Option values:
# use Some2;
type NameId = ;
let nid = A;
let = nid.into;
assert_eq!;
assert_eq!;
Most methods on a "someval" use a copy/move receiver and each provides an as_ref method to
convert to references (similar to [Option::as_ref] and [Result::as_ref], not to be confused
with [AsRef::as_ref]):
# use Some2;
type NameId = ;
let nid = A;
let idref: &u64 = match nid.as_ref ;
assert_eq!;
Individual accessor methods give an Option for components (similar to [Result::ok] and
[Result::err]):
# use Some2;
type NameId = ;
let nid = A;
assert_eq!;
assert_eq!;