Skip to content

Commit

Permalink
Add then with Result support
Browse files Browse the repository at this point in the history
  • Loading branch information
skoppe committed Aug 21, 2024
1 parent 498e2ad commit 6b0d5d4
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
48 changes: 41 additions & 7 deletions source/concurrency/operations/then.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,50 @@ private struct ThenReceiver(Receiver, Value, Fun) {
Fun fun;
static if (is(Value == void)) {
void setValue() @safe {
static if (is(ReturnType!Fun == void)) {
fun();
receiver.setValue();
} else
receiver.setValue(fun());
static if (is(ReturnType!Fun == Result!T, T)) {
auto r = fun();
r.match!((Cancelled c) {
receiver.setDone();
}, (Exception e) {
receiver.setError(e);
}, (Result!(T).Value v) {
static if (is(typeof(v) == Completed)) {
receiver.setValue();
} else {
receiver.setValue(v);
}
});
} else {
static if (is(ReturnType!Fun == void)) {
fun();
receiver.setValue();
} else
receiver.setValue(fun());
}
}
} else {
import std.typecons : isTuple;
enum isExpandable = isTuple!Value && __traits(compiles, {
fun(Value.init.expand);
});
void setValue(Value value) @safe {
static if (is(ReturnType!Fun == void)) {
static if (is(ReturnType!Fun == Result!T, T)) {
static if (isExpandable)
auto r = fun(value.expand);
else
auto r = fun(value);
r.match!((Cancelled c) {
receiver.setDone();
}, (Exception e) {
receiver.setError(e);
}, (Result!(T).Value v) {
static if (is(typeof(v) == Completed)) {
receiver.setValue();
} else {
receiver.setValue(v);
}
});
} else static if (is(ReturnType!Fun == void)) {
static if (isExpandable)
fun(value.expand);
else
Expand Down Expand Up @@ -60,7 +91,10 @@ private struct ThenReceiver(Receiver, Value, Fun) {
struct ThenSender(Sender, Fun) if (models!(Sender, isSender)) {
import std.traits : ReturnType;
static assert(models!(typeof(this), isSender));
alias Value = ReturnType!fun;
static if (is(ReturnType!fun == Result!T, T))
alias Value = T;
else
alias Value = ReturnType!fun;
Sender sender;
Fun fun;
auto connect(Receiver)(return Receiver receiver) @safe return scope {
Expand Down
20 changes: 20 additions & 0 deletions tests/ut/concurrency/operations.d
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,26 @@ unittest {
.shouldEqual(3);
}

@("then.result.value") @safe
unittest {
just(3).then((int i) => Result!int(i)).syncWait.value.should == 3;
}

@("then.result.completed") @safe
unittest {
just(3).then((int i) => Result!void(Completed())).syncWait.isOk.should == true;
}

@("then.result.cancelled") @safe
unittest {
just(3).then((int i) => Result!int(Cancelled())).syncWait.isCancelled;
}

@("then.result.error") @safe
unittest {
just(3).then((int i) => Result!int(new Exception("stuff"))).syncWait.value.shouldThrowWithMessage("stuff");
}

@("whenAll.basic") @safe
unittest {
whenAll(ValueSender!int(1), ValueSender!int(2)).syncWait.value.should
Expand Down

0 comments on commit 6b0d5d4

Please sign in to comment.