1 /**
2 * Copyright © DiamondMVC 2019
3 * License: MIT (https://github.com/DiamondMVC/Diamond/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 */
6 module diamond.controllers.rest.parser;
7
8 import diamond.core.apptype;
9
10 static if (isWeb)
11 {
12 import std..string : strip;
13 import std.array : array, split;
14 import std.algorithm : filter, map;
15
16 import diamond.controllers.rest.routetype;
17 import diamond.controllers.rest.routedatatype;
18 import diamond.controllers.rest.routepart;
19 import diamond.errors;
20
21 package (diamond.controllers):
22
23 /**
24 * Parses a special route.
25 * Params:
26 * route = The route to parse.
27 * Returns:
28 * The parts of the route.
29 */
30 RoutePart[] parseRoute(string route)
31 {
32 if (!route || !route.strip().length) return [];
33
34 if (route[0] == '/')
35 {
36 route = route[1 .. $];
37 }
38
39 if (route[$-1] == '/')
40 {
41 route = route[0 .. $-1];
42 }
43
44 auto routeData = route
45 .split("/")
46 .map!(r => r.strip())
47 .filter!(r => r.length)
48 .array;
49
50 RoutePart[] parts;
51
52 foreach (i; 0 .. routeData.length)
53 {
54 auto data = routeData[i];
55 auto part = new RoutePart;
56
57 if (i == 0)
58 {
59 part.routeType = RouteType.action;
60 part.identifier = data;
61 }
62 else if (data == "*")
63 {
64 part.routeType = RouteType.wildcard;
65 }
66 else if (data[0] == '{' && data[$-1] == '}')
67 {
68 auto typeData = data[1 .. $-1].split(":");
69
70 part.type = cast(RouteDataType)typeData[0];
71
72 if (typeData.length == 1)
73 {
74 part.routeType = RouteType.type;
75 }
76 else if (typeData.length == 2)
77 {
78 part.routeType = RouteType.typeIdentifier;
79 part.identifier = typeData[1];
80 }
81 else
82 {
83 throw new RouteException("Invalid type identifier for route.");
84 }
85 }
86 else
87 {
88 part.identifier = data;
89 part.routeType = RouteType.identifier;
90 }
91
92 parts ~= part;
93 }
94
95 return parts;
96 }
97 }