Skip to content

Commit a12eff0

Browse files
committed
Add client support for default parameters
The change was quite trivial, and is not required when using an interface instead of the RemoteAPI instance.
1 parent 5d28036 commit a12eff0

File tree

1 file changed

+77
-3
lines changed

1 file changed

+77
-3
lines changed

source/geod24/LocalRest.d

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,25 @@ public struct Listener (API)
631631
package BindChn data;
632632
}
633633

634+
/// Helper template to allow default parameters to work
635+
private template ParamsRef (alias Func)
636+
{
637+
import std.meta : EraseAll;
638+
import std.traits : ParameterDefaults;
639+
640+
/// All of the function parameters
641+
private alias All = Parameters!Func;
642+
643+
/// Default parameters matching `Optional`
644+
private enum Default = EraseAll!(void, ParameterDefaults!Func);
645+
646+
/// Only parameters that don't have a default
647+
private alias Required = All[0 .. $ - Default.length];
648+
649+
/// Parameters with a default value
650+
private alias Optional = All[$ - Default.length .. $];
651+
}
652+
634653
/*******************************************************************************
635654
636655
A reference to an alread-instantiated node
@@ -1221,13 +1240,14 @@ public final class RemoteAPI (API, alias S = VibeJSONSerializer!()) : API
12211240
static foreach (ovrld; __traits(getOverloads, API, member))
12221241
{
12231242
mixin(q{
1224-
override ReturnType!(ovrld) } ~ member ~ q{ (Parameters!ovrld params)
1243+
override ReturnType!(ovrld) } ~ member ~ q{ (
1244+
ParamsRef!(ovrld).Required required,
1245+
ParamsRef!(ovrld).Optional optional = ParamsRef!(ovrld).Default)
12251246
{
1226-
12271247
// `geod24.concurrency.send/receive[Only]` is not `@safe` but
12281248
// this overload needs to be
12291249
auto res = () @trusted {
1230-
auto serialized = S.serialize(ArgWrapper!(Parameters!ovrld)(params));
1250+
auto serialized = S.serialize(ArgWrapper!(Parameters!ovrld)(required, optional));
12311251
auto command = Command(this.conn.getNextCommandId(), ovrld.mangleof, SerializedData(serialized));
12321252

12331253
if(!this.conn.sendCommand(command))
@@ -2713,3 +2733,57 @@ unittest
27132733
atomicStore(node1Addr, node1.ctrl.listener());
27142734
node1.call0();
27152735
}
2736+
2737+
// Make sure default parameters work correctly
2738+
unittest
2739+
{
2740+
static interface API
2741+
{
2742+
public uint call1 (uint value = 69) @safe;
2743+
public size_t call2 (string required, string optional = "Hello world") @safe;
2744+
public size_t call3 (string file = __FILE__, uint line = __LINE__) @safe; // L2744
2745+
}
2746+
2747+
static class Node : API
2748+
{
2749+
public override uint call1 (uint value) @safe
2750+
{
2751+
return value;
2752+
}
2753+
2754+
public override size_t call2 (string required, string optional) @safe
2755+
{
2756+
return required.length + optional.length;
2757+
}
2758+
2759+
public override size_t call3 (string file, uint line) @safe
2760+
{
2761+
// Test disabled. With LDC v1.28.1 installed with Homebrew on MacOS,
2762+
// the defaults I got were:
2763+
// file: "/usr/local/opt/dmd/include/dlang/dmd/std/traits.d"
2764+
// line: 1444
2765+
return file.length + line;
2766+
}
2767+
}
2768+
2769+
auto node1 = RemoteAPI!API.spawn!Node();
2770+
scope (exit)
2771+
{
2772+
node1.ctrl.shutdown();
2773+
thread_joinAll();
2774+
}
2775+
2776+
assert(node1.call1() == 69);
2777+
assert(node1.call1(42) == 42);
2778+
assert(node1.call2("WYSIWYG") == "WYSIWYG".length + "Hello World".length);
2779+
assert(node1.call2("WYSIWYG", null) == "WYSIWYG".length);
2780+
version (none)
2781+
{
2782+
// Does not work! There are various issues.
2783+
// First, https://issues.dlang.org/show_bug.cgi?id=18919 means we'd probably
2784+
// get the wrong line. But worse, because of `std.traits` eagerly interpreting
2785+
// the default (e.g. see https://issues.dlang.org/show_bug.cgi?id=14369),
2786+
// the `__FILE__` we get is actually... std.traits! And the line to match.
2787+
assert(node1.call3() == __FILE__.length + __LINE__);
2788+
}
2789+
}

0 commit comments

Comments
 (0)