Skip to content

Commit d8f66a1

Browse files
committed
Fix handling of enum parameters for REST interface clients.
Instead of by name, enum values were serialized by value, causing a conversion error on the server side.
1 parent 98ee426 commit d8f66a1

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

tests/rest/source/app.d

+14
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,8 @@ interface Example8API
483483
double d;
484484
}
485485

486+
enum E { foo, bar }
487+
486488
FooType constFoo (const FooType param);
487489
FooType constRefFoo (const ref FooType param);
488490
FooType inFoo (in FooType param);
@@ -491,6 +493,7 @@ interface Example8API
491493
int[] constRefArr (const ref int[] param);
492494
int[] inArr (in int[] param);
493495
int[] immutableArr (immutable int[] param);
496+
E getEnum(E value);
494497
}
495498

496499
class Example8 : Example8API
@@ -536,6 +539,14 @@ class Example8 : Example8API
536539
{
537540
return param;
538541
}
542+
543+
E getEnum(E value)
544+
{
545+
final switch (value) {
546+
case E.foo: return E.bar;
547+
case E.bar: return E.foo;
548+
}
549+
}
539550
}
540551

541552
unittest
@@ -552,6 +563,7 @@ unittest
552563
assert (routes[5].method == HTTPMethod.POST && routes[5].pattern == "/example8_api/const_ref_arr");
553564
assert (routes[6].method == HTTPMethod.POST && routes[6].pattern == "/example8_api/in_arr");
554565
assert (routes[7].method == HTTPMethod.POST && routes[7].pattern == "/example8_api/immutable_arr");
566+
assert (routes[8].method == HTTPMethod.GET && routes[7].pattern == "/example8_api/enum");
555567
}
556568

557569
void runTests(string url)
@@ -714,6 +726,8 @@ void runTests(string url)
714726
assert(arr.equal(api.constRefArr(arr)));
715727
assert(arr.equal(api.immutableArr(cast(immutable(int[])) arr)));
716728
assert(arr.equal(api.inArr(arr)));
729+
assert(api.getEnum(Example8API.E.foo) == Example8API.E.bar);
730+
assert(api.getEnum(Example8API.E.bar) == Example8API.E.foo);
717731
}
718732
}
719733

web/vibe/web/rest.d

+17-10
Original file line numberDiff line numberDiff line change
@@ -1868,8 +1868,7 @@ private auto executeClientMethod(I, size_t ridx, ARGS...)
18681868
query.filterURLEncode(ARGS[i].toString());
18691869
else
18701870
// Note: CTFE triggers compiler bug here (think we are returning Json, not string).
1871-
query.filterURLEncode(toRestString(
1872-
serializeWithPolicy!(JsonSerializer, SerPolicyType)(ARGS[i])));
1871+
query.filterURLEncode(toRestString!SerPolicyType(ARGS[i]));
18731872
}
18741873

18751874
foreach (i, PT; PTT) {
@@ -1914,7 +1913,7 @@ private auto executeClientMethod(I, size_t ridx, ARGS...)
19141913
foreach (j, PT; PTT) {
19151914
static if (sroute.parameters[j].name[0] == '_' || sroute.parameters[j].name == "id") {
19161915
case sroute.parameters[j].name:
1917-
url ~= urlEncode(toRestString(serializeToJson(ARGS[j])));
1916+
url ~= urlEncode(toRestString(ARGS[j]));
19181917
goto sbrk;
19191918
}
19201919
}
@@ -2103,14 +2102,22 @@ private {
21032102
import vibe.data.json;
21042103
import std.conv : to;
21052104

2106-
string toRestString(Json value)
2105+
string toRestString(alias SerPolicyType = DefaultPolicy, T)(T value)
21072106
@safe {
2108-
switch (value.type) {
2109-
default: return value.toString();
2110-
case Json.Type.bool_: return value.get!bool ? "true" : "false";
2111-
case Json.Type.int_: return to!string(value.get!long);
2112-
case Json.Type.float_: return to!string(value.get!double);
2113-
case Json.Type.string: return value.get!string;
2107+
import std.array : Appender, appender;
2108+
import std.uuid : UUID;
2109+
static if (isInstanceOf!(Nullable, T)) return T(fromRestString!(typeof(T.init.get()))(value));
2110+
else static if (is(T == bool)) return value ? "true" : "false";
2111+
else static if (is(T : int)) return to!string(value);
2112+
else static if (is(T : double)) return to!string(value); // FIXME: formattedWrite(dst, "%.16g", json.get!double);
2113+
else static if (is(string : T)) return value;
2114+
else static if (__traits(compiles, value.toISOExtString)) return value.toISOExtString;
2115+
else static if (__traits(compiles, value.toString)) return value.toString;
2116+
else static if (is(T == UUID)) return value.toString();
2117+
else {
2118+
auto ret = appender!string;
2119+
serializeWithPolicy!(JsonStringSerializer!(Appender!string), SerPolicyType, T)(value, ret);
2120+
return ret.data;
21142121
}
21152122
}
21162123

0 commit comments

Comments
 (0)