1 module dcord.api.routes;
2 
3 import std.format,
4        std.array,
5        std.typecons,
6        std.algorithm.searching;
7 
8 import vibe.http.client;
9 
10 private string safeFormat(T...)(inout(string) fmt, T args) {
11   import std.format : formattedWrite, FormatException;
12   import std.array : appender;
13   auto w = appender!(immutable(char)[]);
14   auto n = formattedWrite(w, fmt, args);
15   return w.data;
16 }
17 
18 private string replaceMajorVariables(string data) {
19   return data.replace("$GUILD", "%s").replace("$CHANNEL", "%s");
20 }
21 
22 alias Bucket = Tuple!(HTTPMethod, string);
23 
24 struct CompiledRoute {
25   Route route;
26   string key;
27   string compiled;
28 
29   @property Bucket bucket() {
30     return tuple(this.route.method, this.key);
31   }
32 
33   @property HTTPMethod method() {
34     return this.route.method;
35   }
36 }
37 
38 struct Route {
39   HTTPMethod method;
40   string url;
41 
42   this(HTTPMethod method, string url) {
43     this.method = method;
44     this.url = url;
45   }
46 
47   CompiledRoute opCall(T...)(T args) {
48     // First generate the keyed route
49     string key = safeFormat(replaceMajorVariables(this.url.replace("%s", "")), args);
50 
51     // Then generate the actual request url
52     string url = format(replaceMajorVariables(this.url), args); 
53     return CompiledRoute(this, key, url);
54   }
55 }
56 
57 enum Routes: Route {
58   GATEWAY_GET = Route(HTTPMethod.GET, "/gateway"),
59 
60   CHANNELS_GET = Route(HTTPMethod.GET, "/channels/$CHANNEL"),
61   CHANNELS_MODIFY = Route(HTTPMethod.PATCH, "/channels/$CHANNEL"),
62   CHANNELS_DELETE = Route(HTTPMethod.DELETE, "/channels/$CHANNEL"),
63 
64   CHANNELS_MESSAGES_LIST = Route(HTTPMethod.GET, "/channels/$CHANNEL/messages"),
65   CHANNELS_MESSAGES_GET = Route(HTTPMethod.GET, "/channels/$CHANNEL/messages/%s"),
66   CHANNELS_MESSAGES_CREATE = Route(HTTPMethod.POST, "/channels/$CHANNEL/messages"),
67   CHANNELS_MESSAGES_MODIFY = Route(HTTPMethod.PATCH, "/channels/$CHANNEL/messages/%s"),
68   CHANNELS_MESSAGES_DELETE = Route(HTTPMethod.DELETE, "/channels/$CHANNEL/messages/%s"),
69   CHANNELS_MESSAGES_DELETE_BULK = Route(HTTPMethod.POST, "/channels/$CHANNEL/messages/bulk_delete"),
70 
71   CHANNELS_PERMISSIONS_MODIFY = Route(HTTPMethod.PUT, "/channels/$CHANNEL/permissions/%s"),
72   CHANNELS_PERMISSIONS_DELETE = Route(HTTPMethod.DELETE, "/channels/$CHANNEL/permissions/%s"),
73   CHANNELS_INVITES_LIST = Route(HTTPMethod.GET, "/channels/$CHANNEL/invites"),
74   CHANNELS_INVITES_CREATE = Route(HTTPMethod.POST, "/channels/$CHANNEL/invites"),
75 
76   CHANNELS_PINS_LIST = Route(HTTPMethod.GET, "/channels/$CHANNEL/pins"),
77   CHANNELS_PINS_CREATE = Route(HTTPMethod.PUT, "/channels/$CHANNEL/pins/%s"),
78   CHANNELS_PINS_DELETE = Route(HTTPMethod.DELETE, "/channels/$CHANNEL/pins/%s"),
79 
80   GUILDS_GET = Route(HTTPMethod.GET, "/guilds/$GUILD"),
81   GUILDS_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD"),
82   GUILDS_DELETE = Route(HTTPMethod.DELETE, "/guilds/$GUILD"),
83   GUILDS_CHANNELS_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/channels"),
84   GUILDS_CHANNELS_CREATE = Route(HTTPMethod.POST, "/guilds/$GUILD/channels"),
85   GUILDS_CHANNELS_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD/channels"),
86   GUILDS_MEMBERS_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/members"),
87   GUILDS_MEMBERS_GET = Route(HTTPMethod.GET, "/guilds/$GUILD/members/%s"),
88   GUILDS_MEMBERS_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD/members/%s"),
89   GUILDS_MEMBERS_KICK = Route(HTTPMethod.DELETE, "/guilds/$GUILD/members/%s"),
90   GUILDS_BANS_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/bans"),
91   GUILDS_BANS_CREATE = Route(HTTPMethod.PUT, "/guilds/$GUILD/bans/%s"),
92   GUILDS_BANS_DELETE = Route(HTTPMethod.DELETE, "/guilds/$GUILD/bans/%s"),
93   GUILDS_ROLES_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/roles"),
94   GUILDS_ROLES_CREATE = Route(HTTPMethod.POST, "/guilds/$GUILD/roles"),
95   GUILDS_ROLES_MODIFY_BATCH = Route(HTTPMethod.PATCH, "/guilds/$GUILD/roles"),
96   GUILDS_ROLES_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD/roles/%s"),
97   GUILDS_ROLES_DELETE = Route(HTTPMethod.DELETE, "/guilds/$GUILD/roles/%s"),
98   GUILDS_PRUNE_COUNT = Route(HTTPMethod.GET, "/guilds/$GUILD/prune"),
99   GUILDS_PRUNE_BEGIN = Route(HTTPMethod.POST, "/guilds/$GUILD/prune"),
100   GUILDS_VOICE_REGIONS_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/regions"),
101   GUILDS_INVITES_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/invites"),
102   GUILDS_INTEGRATIONS_LIST = Route(HTTPMethod.GET, "/guilds/$GUILD/integrations"),
103   GUILDS_INTEGRATIONS_CREATE = Route(HTTPMethod.POST, "/guilds/$GUILD/integrations"),
104   GUILDS_INTEGRATIONS_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD/integrations/%s"),
105   GUILDS_INTEGRATIONS_DELETE = Route(HTTPMethod.DELETE, "/guilds/$GUILD/integrations/%s"),
106   GUILDS_INTEGRATIONS_SYNC = Route(HTTPMethod.POST, "/guilds/$GUILD/integrations/%s/sync"),
107   GUILDS_EMBED_GET = Route(HTTPMethod.GET, "/guilds/$GUILD/embed"),
108   GUILDS_EMBED_MODIFY = Route(HTTPMethod.PATCH, "/guilds/$GUILD/embed"),
109   USERS_ME_GET = Route(HTTPMethod.GET, "/users/@me"),
110   USERS_ME_PATCH = Route(HTTPMethod.PATCH, "/users/@me"),
111   USERS_ME_GUILDS_LIST = Route(HTTPMethod.GET, "/users/@me/guilds"),
112   USERS_ME_GUILDS_LEAVE = Route(HTTPMethod.DELETE, "/users/@me/guilds/$GUILD"),
113   USERS_ME_DMS_LIST = Route(HTTPMethod.GET, "/users/@me/channels"),
114   USERS_ME_DMS_CREATE = Route(HTTPMethod.POST, "/users/@me/channels"),
115   USERS_ME_CONNECTIONS_LIST = Route(HTTPMethod.GET, "/users/@me/connections"),
116   USERS_GET = Route(HTTPMethod.GET, "/users/%s"),
117 
118   INVITES_GET = Route(HTTPMethod.GET, "/invites/%s"),
119   INVITES_DELETE = Route(HTTPMethod.DELETE, "/invites/%s"),
120 
121   WEBHOOKS_CREATE = Route(HTTPMethod.POST, "/channels/%s/webhooks"),
122   WEBHOOKS_DELETE = Route(HTTPMethod.DELETE, "/webhooks/%s"),
123   WEBHOOKS_GET = Route(HTTPMethod.GET, "/webhooks/%s"),
124   WEBHOOKS_EXECUTE = Route(HTTPMethod.POST, "/webhooks/%s/%s"),
125 
126   REACTIONS_CREATE = Route(HTTPMethod.PUT, "/channels/%s/messages/%s/reactions/%s/@me"),
127 }
128