Skip to content

Commit 1d42e51

Browse files
committed
Endpoint fallthrough implemented
1 parent c669ff2 commit 1d42e51

File tree

4 files changed

+80
-10
lines changed

4 files changed

+80
-10
lines changed

source/serverino/config.d

+6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ import std.stdio : File;
3232
import std.datetime : Duration, seconds, hours, msecs;
3333
import std.traits : ReturnType;
3434

35+
public enum Fallthrough : bool
36+
{
37+
Yes = true,
38+
No = false
39+
}
40+
3541
public struct priority { long priority; } /// UDA. Set @endpoint priority
3642

3743
public enum endpoint; /// UDA. Functions with @endpoint attached are called when a request is received

source/serverino/worker.d

+30-9
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ struct Worker
907907
static if (hasUDA!(f, route))
908908
{
909909
// If one of the route UDAs returns true, we will launch the function.
910-
bool willLaunchFunc()
910+
bool willLaunchFunc()()
911911
{
912912
static foreach(attr; getUDAs!(f, route))
913913
{
@@ -919,19 +919,40 @@ struct Worker
919919

920920
bool willLaunch = willLaunchFunc();
921921
}
922-
else immutable willLaunch = true;
922+
else enum willLaunch = true;
923+
924+
request._internal._route ~= ff.mod ~ "." ~ ff.name;
923925

924926
if (willLaunch)
925927
{
926-
static if (__traits(compiles, f(request, output))) f(request, output);
927-
else static if (__traits(compiles, f(request))) f(request);
928-
else f(output);
929-
}
928+
// Temporarily set the dirty flag to false. It will be restored at the end of the function.
929+
bool wasDirty = output._internal._dirty;
930+
if (wasDirty) output._internal._dirty = false;
931+
scope(exit) if (wasDirty) output._internal._dirty = true;
930932

931-
request._internal._route ~= ff.mod ~ "." ~ ff.name;
932-
}
933+
import std.meta : AliasSeq;
934+
935+
// Get the parameters of the function
936+
static if (__traits(compiles, f(request, output))) auto params = AliasSeq!(request, output);
937+
else static if (__traits(compiles, f(request))) auto params = AliasSeq!(request);
938+
else auto params = AliasSeq!(output);
939+
940+
// Check if the function has a fallthrough return value
941+
Fallthrough tmpFt;
942+
enum withFallthrough = __traits(compiles, tmpFt = f(params));
933943

934-
if (output._internal._dirty) return true;
944+
static if (withFallthrough)
945+
{
946+
if (f(params) == Fallthrough.No) return true;
947+
}
948+
else
949+
{
950+
f(params);
951+
if (output._internal._dirty) return true;
952+
}
953+
954+
}
955+
}
935956
}
936957

937958
return false;

tests/test-01/source/app.d

+43
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,35 @@ void test_3(Request r, Output o)
230230

231231
}
232232

233+
@endpoint @route!(x => x.path == "/fallthrough") @priority(400)
234+
auto fallthrough1(Request r, Output o)
235+
{
236+
o ~= "fallthrough ";
237+
return Fallthrough.Yes;
238+
}
239+
240+
@endpoint @route!(x => x.path == "/fallthrough") @priority(300)
241+
void fallthrough2(Request r, Output o)
242+
{
243+
// Nothing happens
244+
info("running fallthrough 2()");
245+
}
246+
247+
@endpoint @route!(x => x.path == "/fallthrough") @priority(200)
248+
void fallthrough3(Request r, Output o)
249+
{
250+
o ~= "works!";
251+
}
252+
253+
@endpoint @route!(x => x.path == "/fallthrough") @priority(100)
254+
void fallthrough4(Request r, Output o)
255+
{
256+
o ~= "doesn't works!";
257+
}
258+
259+
260+
261+
233262
@onServerInit
234263
ServerinoConfig conf()
235264
{
@@ -608,4 +637,18 @@ Content-Type: application/json\r
608637
remove("test_serverino_file.json");
609638

610639
}
640+
641+
// Fallthrough
642+
643+
{
644+
string content;
645+
646+
auto http = HTTP("http://127.0.0.1:8080/fallthrough");
647+
http.onReceive = (ubyte[] data) { content ~= data; return data.length; };
648+
http.perform();
649+
650+
assert(content == "fallthrough works!", content);
651+
assert(http.statusLine.code == 200);
652+
}
653+
611654
}

tests/test-01/source/tagged.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ void test_3(Request r, Output o) { if (r.path == "/error") return; history ~= 3;
4343
void test_4(Request r, Output o) { if (r.path == "/error") return; history ~= 4; o ~= "4"; }
4444

4545
@endpoint @priority(4)
46-
void test_5(Request r) { history ~= 5; return; }
46+
void test_5(Request r, Output o) { history ~= 5; }
4747

4848
// Functions missing the @endpoint attribute
4949
@priority(4) void wrong_function(Request r) { return; }

0 commit comments

Comments
 (0)