1 module dcord.types.permission;
2 
3 import std.format,
4        std.algorithm.iteration;
5 
6 import dcord.types;
7 
8 /// Raised when an action cannot be performed due to a lack of permissions
9 class PermissionsError: Exception {
10   Permissions perm;
11 
12   this(T...)(Permissions perm, T args) {
13     this.perm = perm;
14     super(format("Permission required: %s", perm));
15   }
16 }
17 
18 /// Permission value
19 alias Permission = ulong;
20 
21 /// Enumeration of permissions.
22 enum Permissions: Permission {
23   NONE,
24   CREATE_INSTANT_INVITE = 1 << 0,
25   KICK_MEMBERS = 1 << 1,
26   BAN_MEMBERS = 1 << 2,
27   ADMINISTRATOR = 1 << 3,
28   MANAGE_CHANNELS = 1 << 4,
29   MANAGE_GUILD = 1 << 5,
30   READ_MESSAGES = 1 << 10,
31   SEND_MESSAGES = 1 << 11,
32   SEND_TSS_MESSAGES = 1 << 12,
33   MANAGE_MESSAGES = 1 << 13,
34   EMBED_LINKS = 1 << 14,
35   ATTACH_FILES = 1 << 15,
36   READ_MESSAGE_HISTORY = 1 << 16,
37   MENTION_EVERYONE = 1 << 17,
38   CONNECT = 1 << 20,
39   SPEAK = 1 << 21,
40   MUTE_MEMBERS = 1 << 22,
41   DEAFEN_MEMBERS = 1 << 23,
42   MOVE_MEMBERS = 1 << 24,
43   USE_VAD = 1 << 25,
44   CHANGE_NICKNAME = 1 << 26,
45   MANAGE_NICKNAMES = 1 << 27,
46   MANAGE_ROLES = 1 << 28,
47 }
48 
49 /// Interface representing something that contains permissions (e.g. guild/channel)
50 interface IPermissible {
51   Permission getPermissions(Snowflake user);
52 }
53 
54 /// Mixing for IPermissible
55 mixin template Permissible() {
56   /// Returns whether the given user id has a given permission
57   bool can(Snowflake user, Permission perm) {
58     auto perms = this.getPermissions(user);
59 
60     return
61       ((perms & Permissions.ADMINISTRATOR) == Permissions.ADMINISTRATOR) ||
62       ((this.getPermissions(user) & perm) == perm);
63   }
64 
65   /// Returns whether the given user id has all of the given permissions
66   bool can(Snowflake user, Permission[] some...) {
67     return some.map!(p => this.can(user, p)).all();
68   }
69 
70   /// Returns whether the given user has a given permission
71   bool can(User user, Permission perm) {
72     return can(user.id, perm);
73   }
74 
75   /// Returns whether the given user has all of the given permissions
76   bool can(User user, Permission[] some...) {
77     return can(user.id, some);
78   }
79 }