Skip to content

Commit b33a997

Browse files
committed
usability tweaks of orElse
1 parent 7ca41f7 commit b33a997

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

source/expected.d

+24-5
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,9 @@ E expectErr(EX : Expected!(T, E, H), T, E, H)(auto ref EX res, lazy string msg)
14851485
Returns the error contained within the $(LREF Expected) _and then_ another value if there's no error.
14861486
This function can be used for control flow based on $(LREF Expected) values.
14871487
1488+
Predicate can accept no arguments, variable arguments, or previous result value with additional variable arguments.
1489+
It must return $(LREF Expected) wth the same error type. But can provide different value type.
1490+
14881491
Params:
14891492
exp = The $(LREF Expected) to call andThen on
14901493
value = The value to return if there isn't an error
@@ -1500,8 +1503,6 @@ auto ref andThen(EX : Expected!(T, E, H), VEX : Expected!(VT, E, H), T, VT, E, H
15001503
/// ditto
15011504
auto ref andThen(alias pred, EX : Expected!(T, E, H), T, E, H, Args...)(auto ref EX exp, Args args)
15021505
{
1503-
import std.traits : TemplateArgsOf;
1504-
15051506
static if (!is(T == void) && is(typeof(pred(T.init, args)) : Expected!(VT, E, H), VT))
15061507
{
15071508
static if (is(T == VT)) return exp.hasError ? exp : pred(exp.value, args);
@@ -1554,6 +1555,9 @@ unittest
15541555
Returns the value contained within the $(LREF Expected) _or else_ another value if there's an error.
15551556
This function can be used for control flow based on $(LREF Expected) values.
15561557
1558+
Predicate can accept no arguments, variable arguments, or previous result error value with additional variable arguments.
1559+
It must return $(LREF Expected) wth the same value type. But can provide different error value type.
1560+
15571561
Params:
15581562
exp = The $(LREF Expected) to call orElse on
15591563
value = The value to return if there is an error
@@ -1571,9 +1575,19 @@ auto ref orElse(alias pred, EX : Expected!(T, E, H), T, E, H, Args...)(
15711575
{
15721576
static if (is(typeof(pred(args)) : T))
15731577
return exp.hasError ? pred(args) : exp.value;
1574-
else static if (is(typeof(pred(args)) : EX))
1575-
return exp.hasError ? pred() : exp;
1576-
else static assert(0, "Expecting predicate of same value type as source Expected or predicate of same Expected type");
1578+
else static if (is(typeof(pred(exp.error, args)) : T))
1579+
return exp.hasError ? pred(exp.error, args) : exp.value;
1580+
else static if (is(typeof(pred(args)) : Expected!(T, VE, H), VE))
1581+
{
1582+
static if (is(E == VE)) return exp.hasError ? pred(args) : exp;
1583+
else return exp.hasError ? pred(args) : ok!VE(exp.value);
1584+
}
1585+
else static if (is(typeof(pred(exp.error, args)) : Expected!(T, VE, H), VE))
1586+
{
1587+
static if (is(E == VE)) return exp.hasError ? pred(exp.error, args) : exp;
1588+
else return exp.hasError ? pred(exp.error, args) : ok!VE(exp.value);
1589+
}
1590+
else static assert(0, "Expecting predicate of same value type");
15771591
}
15781592

15791593
///
@@ -1595,6 +1609,11 @@ unittest
15951609

15961610
// with args
15971611
assert(err!int("foo").orElse!((v) => v)(42) == 42);
1612+
1613+
// with different error type
1614+
assert(err!int("foo").orElse!((v) => ok!int(v))(42).value == 42); // string -> int
1615+
assert(err!int("foo").orElse!((v) => err!int(v))(42).error == 42);
1616+
assert(err!int("foo").orElse!((e, v) => err!int(e.length + v))(42).error == 45); // with previous error
15981617
}
15991618

16001619
/++

0 commit comments

Comments
 (0)