-
Notifications
You must be signed in to change notification settings - Fork 15
ValueOrError
SuccincT.Options.ValueOrError
Provides a special-case union of two string values: one representing a value; the other an error. For use in situations where a string return type is needed, by throwing exceptions isn't desirable.
Instances of ValueOrError
cannot be created directly using new
. As both possible values are of type string
, the constructor would need two parameters and messy null
passing, a boolean parameters or similar. Instead use the two static methods WithValue()
and WithError()
.
public static ValueOrError WithValue(string value)
Creates an instance of ValueOrError
holding a value. If value
is null
, an ArgumentNullException
will be thrown.
public static ValueOrError WithError(string error)
Creates an instance of ValueOrError
holding an error. If error
is null
, an ArgumentNullException
will be thrown.
ValueOrError
is a class, not a struct, but it overrides both Equals
and the ==
& !=
operator pair, so instances use value comparison for equality. The following rules apply to equality:
- If an instance of
ValueOrError
holds a value, then it will equal another instance if that also hold a value and that value has the same string content. - If an instance of
ValueOrError
holds an error, then it will equal another instance if that also hold an error and that error has the same string content.
This can be expressed this in code with the following.
var valA = ValueOrError.WithValue("abc");
var valB = ValueOrError.WithValue("abc");
var valC = ValueOrError.WithValue("def");
var errA = ValueOrError.WithError("abc");
var errB = ValueOrError.WithError("abc");
var errC = ValueOrError.WithError("def");
// The following expressions are all true:
valA == valA
valA == valB
valB != valC
valA.Equals(valA)
valA != errA
errA == errA
errA == errB
errB != errC
errA.Equals(errB)
ValueOrError
uses Succinc<T>'s pattern matching capabilities to perform an action or generate a result according to its value/error state. Two versions of the match method are directly supported by ValueOrError
:
public ValueOrErrorMatcher<T> Match()
Match()
supports the construction of pattern matches and actions (void methods) to invoke upon match. The pattern must be terminated with Exec()
.
The format of an option match pattern is as follows:
option.Match()
.Value()<optional guard>.Do(value => action on value)
.Error()<optional guard>.Do(error => action on error)
[.Else(option => action when no match) |
.IgnoreElse()]
.Exec()
Value()
can take an optional guard of two forms:
.Value().Of(value1).Or(value2).Or(value3)...Do(value => action on value)
.Value().Where(value => boolean expression).Do(value => action on value)
Multiple Value()
expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The action is then invoked and no further matching occurs.
Error()
can also take an optional guard of two forms:
.Error().Of(value1).Or(value2).Or(value3)...Do(error => action on error)
.Error().Where(value => boolean expression).Do(error => action on error)
Multiple Error()
expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The action is then invoked and no further matching occurs.
The Else
action is used if no match was found. The ValueOrError
itself is passed as a parameter to the associated action. If no action is required when no match occurs, IgnoreElse
can be used instead.
If no match is found, and no Else()
or IgnoreElse
is defined, a SuccincT.PatternMatchers.NoMatchException
will be thrown
public ValueOrErrorMatcher<T, TResult> Match<T>()
Match<T>()
supports the construction of pattern matches and functions returning a TResult
to invoke upon match. The pattern must be terminated with Result()
.
The format of an option match pattern is as follows:
option.Match<T>()
.Value()<optional guard>.Do(value => func resulting in a T))
.Error()<optional guard>.Do(error => func resulting in a T))
.Else(option => no match func resulting in a T)
.Result()
Value()
can take an optional guard of two forms:
.Value().Of(value1).Or(value2).Or(value3)...Do(value => func resulting in a T))
.Value().Where(value => boolean expression).Do(value => func resulting in a T))
Multiple Value()
expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The function is then invoked and no further matching occurs.
Error()
can also take an optional guard of two forms:
.Error().Of(value1).Or(value2).Or(value3)...Do(error => func resulting in a T))
.Error().Where(value => boolean expression).Do(error => func resulting in a T))
Multiple Error()
expressions may be defined. Each is compared in turn again the value (assume there is one) until a match is found. The function is then invoked and no further matching occurs.
The Else
function is used if no match was found. The option itself is passed as a parameter to the associated function.
If no match is found, and no Else()
defined, a SuccincT.PatternMatchers.NoMatchException
will be thrown
As an alternative to using an option in a functional style, its value can be directly accessed by more traditional, imperative style C# code. three read-only properties are provided for this purpose. In addition, ToString()
is overridden to handle the dual-state nature of its values.
public bool HasValue { get; }**
True if the ValueOrError
has a value; false if it's an error.
public string Value { get; }
If HasValue
is true, this will return the value held. Otherwise it will throw an InvalidOperationException
.
public string Error { get; }
If HasValue
is false, this will return the error held. Otherwise it will throw an InvalidOperationException
.
public override string ToString()
Returns Value of <the value held>
or Error of <the error held>
depending on with a value or error is held, respectively.
Action
/Func
conversionsCycle
methods- Converting between
Action
andFunc
- Extension methods for existing types that use
Option<T>
- Indexed enumerations
IEnumerable<T>
cons- Option-based parsers
- Partial function applications
- Pattern matching
- Pipe Operators
- Typed lambdas
Any
Either<TLeft,TRight>
None
Option<T>
Success<T>
Union<T1,T2>
Union<T1,T2,T3>
Union<T1,T2,T3,T4>
Unit
ValueOrError