discorb 0.18.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +25 -0
  5. data/Gemfile +4 -4
  6. data/README.md +2 -1
  7. data/Rakefile +482 -459
  8. data/Steepfile +8 -6
  9. data/docs/application_command.md +1 -0
  10. data/docs/events.md +2 -2
  11. data/docs/voice_events.md +6 -6
  12. data/lib/discorb/allowed_mentions.rb +68 -72
  13. data/lib/discorb/app_command/command.rb +466 -394
  14. data/lib/discorb/app_command/common.rb +65 -25
  15. data/lib/discorb/app_command/handler.rb +304 -265
  16. data/lib/discorb/app_command.rb +5 -5
  17. data/lib/discorb/application.rb +198 -197
  18. data/lib/discorb/asset.rb +101 -101
  19. data/lib/discorb/attachment.rb +134 -119
  20. data/lib/discorb/audit_logs.rb +412 -385
  21. data/lib/discorb/automod.rb +279 -269
  22. data/lib/discorb/channel/base.rb +107 -108
  23. data/lib/discorb/channel/category.rb +32 -32
  24. data/lib/discorb/channel/container.rb +44 -44
  25. data/lib/discorb/channel/dm.rb +26 -28
  26. data/lib/discorb/channel/guild.rb +311 -246
  27. data/lib/discorb/channel/stage.rb +156 -140
  28. data/lib/discorb/channel/text.rb +430 -336
  29. data/lib/discorb/channel/thread.rb +374 -325
  30. data/lib/discorb/channel/voice.rb +85 -79
  31. data/lib/discorb/channel.rb +5 -5
  32. data/lib/discorb/client.rb +635 -623
  33. data/lib/discorb/color.rb +178 -182
  34. data/lib/discorb/common.rb +168 -164
  35. data/lib/discorb/components/button.rb +107 -106
  36. data/lib/discorb/components/select_menu.rb +157 -145
  37. data/lib/discorb/components/text_input.rb +103 -106
  38. data/lib/discorb/components.rb +68 -66
  39. data/lib/discorb/dictionary.rb +135 -135
  40. data/lib/discorb/embed.rb +404 -398
  41. data/lib/discorb/emoji.rb +309 -302
  42. data/lib/discorb/emoji_table.rb +16099 -8857
  43. data/lib/discorb/error.rb +131 -131
  44. data/lib/discorb/event.rb +360 -314
  45. data/lib/discorb/event_handler.rb +39 -39
  46. data/lib/discorb/exe/about.rb +17 -17
  47. data/lib/discorb/exe/irb.rb +72 -67
  48. data/lib/discorb/exe/new.rb +323 -315
  49. data/lib/discorb/exe/run.rb +69 -68
  50. data/lib/discorb/exe/setup.rb +57 -55
  51. data/lib/discorb/exe/show.rb +12 -12
  52. data/lib/discorb/extend.rb +25 -45
  53. data/lib/discorb/extension.rb +89 -83
  54. data/lib/discorb/flag.rb +126 -128
  55. data/lib/discorb/gateway.rb +984 -794
  56. data/lib/discorb/gateway_events.rb +670 -638
  57. data/lib/discorb/gateway_requests.rb +45 -48
  58. data/lib/discorb/guild.rb +2115 -1626
  59. data/lib/discorb/guild_template.rb +280 -241
  60. data/lib/discorb/http.rb +247 -232
  61. data/lib/discorb/image.rb +42 -42
  62. data/lib/discorb/integration.rb +169 -161
  63. data/lib/discorb/intents.rb +161 -163
  64. data/lib/discorb/interaction/autocomplete.rb +76 -62
  65. data/lib/discorb/interaction/command.rb +279 -224
  66. data/lib/discorb/interaction/components.rb +114 -104
  67. data/lib/discorb/interaction/modal.rb +36 -32
  68. data/lib/discorb/interaction/response.rb +379 -330
  69. data/lib/discorb/interaction/root.rb +271 -118
  70. data/lib/discorb/interaction.rb +5 -5
  71. data/lib/discorb/invite.rb +154 -153
  72. data/lib/discorb/member.rb +344 -311
  73. data/lib/discorb/message.rb +615 -544
  74. data/lib/discorb/message_meta.rb +197 -186
  75. data/lib/discorb/modules.rb +371 -290
  76. data/lib/discorb/permission.rb +305 -289
  77. data/lib/discorb/presence.rb +352 -346
  78. data/lib/discorb/rate_limit.rb +81 -76
  79. data/lib/discorb/reaction.rb +55 -54
  80. data/lib/discorb/role.rb +272 -240
  81. data/lib/discorb/shard.rb +76 -74
  82. data/lib/discorb/sticker.rb +193 -171
  83. data/lib/discorb/user.rb +205 -188
  84. data/lib/discorb/utils/colored_puts.rb +16 -16
  85. data/lib/discorb/utils.rb +12 -16
  86. data/lib/discorb/voice_state.rb +305 -281
  87. data/lib/discorb/webhook.rb +537 -507
  88. data/lib/discorb.rb +62 -56
  89. data/sig/discorb/activity.rbs +1 -0
  90. data/sig/discorb/allowed_mentions.rbs +1 -0
  91. data/sig/discorb/app_command/base.rbs +7 -1
  92. data/sig/discorb/application.rbs +6 -0
  93. data/sig/discorb/asset.rbs +2 -0
  94. data/sig/discorb/attachment.rbs +8 -0
  95. data/sig/discorb/audit_log.rbs +7 -0
  96. data/sig/discorb/automod.rbs +32 -6
  97. data/sig/discorb/avatar.rbs +1 -0
  98. data/sig/discorb/channel/base.rbs +8 -1
  99. data/sig/discorb/channel/category.rbs +1 -0
  100. data/sig/discorb/channel/container.rbs +4 -0
  101. data/sig/discorb/channel/stage.rbs +4 -0
  102. data/sig/discorb/channel/text.rbs +2 -2
  103. data/sig/discorb/channel/thread.rbs +11 -0
  104. data/sig/discorb/channel/voice.rbs +2 -0
  105. data/sig/discorb/client.rbs +21 -20
  106. data/sig/discorb/color.rbs +6 -0
  107. data/sig/discorb/component/base.rbs +1 -0
  108. data/sig/discorb/component/button.rbs +2 -0
  109. data/sig/discorb/component/select_menu.rbs +4 -0
  110. data/sig/discorb/component/text_input.rbs +1 -0
  111. data/sig/discorb/custom_emoji.rbs +5 -1
  112. data/sig/discorb/dictionary.rbs +2 -0
  113. data/sig/discorb/discord_model.rbs +2 -0
  114. data/sig/discorb/embed.rbs +7 -0
  115. data/sig/discorb/emoji.rbs +1 -0
  116. data/sig/discorb/event_handler.rbs +2 -1
  117. data/sig/discorb/extension.rbs +13 -12
  118. data/sig/discorb/flag.rbs +2 -0
  119. data/sig/discorb/gateway.rbs +5 -0
  120. data/sig/discorb/guild.rbs +8 -4
  121. data/sig/discorb/guild_template.rbs +1 -1
  122. data/sig/discorb/http.rbs +4 -1
  123. data/sig/discorb/image.rbs +2 -0
  124. data/sig/discorb/integration.rbs +1 -1
  125. data/sig/discorb/intents.rbs +4 -3
  126. data/sig/discorb/interaction/base.rbs +36 -0
  127. data/sig/discorb/interaction/message_component.rbs +1 -2
  128. data/sig/discorb/interaction/modal.rbs +1 -2
  129. data/sig/discorb/interaction/responder.rbs +49 -49
  130. data/sig/discorb/invite.rbs +1 -1
  131. data/sig/discorb/member.rbs +2 -0
  132. data/sig/discorb/message.rbs +8 -1
  133. data/sig/discorb/messageable.rbs +1 -4
  134. data/sig/discorb/partial_emoji.rbs +3 -0
  135. data/sig/discorb/permissions.rbs +7 -0
  136. data/sig/discorb/presence.rbs +2 -0
  137. data/sig/discorb/reaction.rbs +5 -1
  138. data/sig/discorb/role.rbs +7 -1
  139. data/sig/discorb/scheduled_event.rbs +2 -1
  140. data/sig/discorb/shard.rbs +2 -1
  141. data/sig/discorb/snowflake.rbs +2 -0
  142. data/sig/discorb/stage_instance.rbs +9 -3
  143. data/sig/discorb/sticker.rbs +1 -1
  144. data/sig/discorb/unicode_emoji.rbs +4 -0
  145. data/sig/discorb/user.rbs +24 -20
  146. data/sig/discorb/webhook.rbs +17 -6
  147. data/sig/discorb/welcome_screen.rbs +1 -0
  148. data/sig/override.rbs +2 -0
  149. metadata +3 -3
@@ -1,289 +1,305 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a permission per guild.
6
- # ## Flag fields
7
- #
8
- # | Field | Value |
9
- # |-------|-------|
10
- # |`1 << 0`|`:create_instant_invite`|
11
- # |`1 << 1`|`:kick_members`|
12
- # |`1 << 2`|`:ban_members`|
13
- # |`1 << 3`|`:administrator`|
14
- # |`1 << 4`|`:manage_channels`|
15
- # |`1 << 5`|`:manage_guild`|
16
- # |`1 << 6`|`:add_reactions`|
17
- # |`1 << 7`|`:view_audit_log`|
18
- # |`1 << 8`|`:priority_speaker`|
19
- # |`1 << 9`|`:stream`|
20
- # |`1 << 10`|`:view_channel`|
21
- # |`1 << 11`|`:send_messages`|
22
- # |`1 << 12`|`:send_tts_messages`|
23
- # |`1 << 13`|`:manage_messages`|
24
- # |`1 << 14`|`:embed_links`|
25
- # |`1 << 15`|`:attach_files`|
26
- # |`1 << 16`|`:read_message_history`|
27
- # |`1 << 17`|`:mention_everyone`|
28
- # |`1 << 18`|`:use_external_emojis`|
29
- # |`1 << 19`|`:view_guild_insights`|
30
- # |`1 << 20`|`:connect`|
31
- # |`1 << 21`|`:speak`|
32
- # |`1 << 22`|`:mute_members`|
33
- # |`1 << 23`|`:deafen_members`|
34
- # |`1 << 24`|`:move_members`|
35
- # |`1 << 25`|`:use_vad`|
36
- # |`1 << 26`|`:change_nickname`|
37
- # |`1 << 27`|`:manage_nicknames`|
38
- # |`1 << 28`|`:manage_roles`|
39
- # |`1 << 29`|`:manage_webhooks`|
40
- # |`1 << 30`|`:manage_emojis`|
41
- # |`1 << 31`|`:use_slash_commands`|
42
- # |`1 << 32`|`:request_to_speak`|
43
- # |`1 << 34`|`:manage_threads`|
44
- # |`1 << 35`|`:use_public_threads`|
45
- # |`1 << 36`|`:use_private_threads`|
46
- #
47
- class Permission < Flag
48
- @bits = {
49
- create_instant_invite: 0,
50
- kick_members: 1,
51
- ban_members: 2,
52
- administrator: 3,
53
- manage_channels: 4,
54
- manage_guild: 5,
55
- add_reactions: 6,
56
- view_audit_log: 7,
57
- priority_speaker: 8,
58
- stream: 9,
59
- view_channel: 10,
60
- send_messages: 11,
61
- send_tts_messages: 12,
62
- manage_messages: 13,
63
- embed_links: 14,
64
- attach_files: 15,
65
- read_message_history: 16,
66
- mention_everyone: 17,
67
- use_external_emojis: 18,
68
- view_guild_insights: 19,
69
- connect: 20,
70
- speak: 21,
71
- mute_members: 22,
72
- deafen_members: 23,
73
- move_members: 24,
74
- use_vad: 25,
75
- change_nickname: 26,
76
- manage_nicknames: 27,
77
- manage_roles: 28,
78
- manage_webhooks: 29,
79
- manage_emojis: 30,
80
- use_slash_commands: 31,
81
- request_to_speak: 32,
82
- manage_threads: 34,
83
- use_public_threads: 35,
84
- use_private_threads: 36,
85
- }.freeze
86
- end
87
-
88
- #
89
- # Represents a permission per channel.
90
- #
91
- class PermissionOverwrite
92
- # @!attribute [r] allow
93
- # @return [Discorb::Permission] The allowed permissions.
94
- # @!attribute [r] deny
95
- # @return [Discorb::Permission] The denied permissions.
96
- # @!attribute [r] allow_value
97
- # @return [Integer] The allowed permissions as an integer.
98
- # @!attribute [r] deny_value
99
- # @return [Integer] The denied permissions as an integer.
100
-
101
- @raw_bits = {
102
- create_instant_invite: 0,
103
- kick_members: 1,
104
- ban_members: 2,
105
- administrator: 3,
106
- manage_channels: 4,
107
- manage_guild: 5,
108
- add_reactions: 6,
109
- view_audit_log: 7,
110
- priority_speaker: 8,
111
- stream: 9,
112
- view_channel: 10,
113
- send_messages: 11,
114
- send_tts_messages: 12,
115
- manage_messages: 13,
116
- embed_links: 14,
117
- attach_files: 15,
118
- read_message_history: 16,
119
- mention_everyone: 17,
120
- use_external_emojis: 18,
121
- view_guild_insights: 19,
122
- connect: 20,
123
- speak: 21,
124
- mute_members: 22,
125
- deafen_members: 23,
126
- move_members: 24,
127
- use_vad: 25,
128
- change_nickname: 26,
129
- manage_nicknames: 27,
130
- manage_roles: 28,
131
- manage_webhooks: 29,
132
- manage_emojis: 30,
133
- use_slash_commands: 31,
134
- request_to_speak: 32,
135
- manage_threads: 34,
136
- use_public_threads: 35,
137
- use_private_threads: 36,
138
- }.freeze
139
- @bits = @raw_bits.transform_values { |v| 1 << v }.freeze
140
-
141
- #
142
- # Initializes a new PermissionOverwrite.
143
- # @private
144
- #
145
- # @param allow [Integer] The allowed permissions.
146
- # @param deny [Integer] The denied permissions.
147
- #
148
- def initialize(allow, deny)
149
- @allow = allow
150
- @deny = deny
151
- end
152
-
153
- def allow
154
- self.class.bits.keys.filter { |field| @allow & self.class.bits[field] != 0 }
155
- end
156
-
157
- alias +@ allow
158
-
159
- def deny
160
- self.class.bits.keys.filter { |field| @deny & self.class.bits[field] != 0 }
161
- end
162
-
163
- alias -@ deny
164
-
165
- def allow_value
166
- @allow
167
- end
168
-
169
- def deny_value
170
- @deny
171
- end
172
-
173
- def inspect
174
- "#<#{self.class} allow=#{allow} deny=#{deny}>"
175
- end
176
-
177
- #
178
- # Converts the permission overwrite to a hash.
179
- #
180
- # @return [Hash] The permission overwrite as a hash.
181
- #
182
- def to_hash
183
- self.class.bits.keys.to_h do |field|
184
- [
185
- field,
186
- if @allow & self.class.bits[field] != 0
187
- true
188
- elsif @deny & self.class.bits[field] != 0
189
- false
190
- end,
191
- ]
192
- end
193
- end
194
-
195
- #
196
- # Union of the permission overwrites.
197
- #
198
- # @param [Discorb::PermissionOverwrite] other The other permission overwrite.
199
- #
200
- # @return [Discorb::PermissionOverwrite] The union of the permission overwrites.
201
- #
202
- def +(other)
203
- result = to_hash
204
- self.class.bits.each_key do |field|
205
- result[field] = other[field] unless other[field].nil?
206
- end
207
- self.class.from_hash(result)
208
- end
209
-
210
- #
211
- # Returns whether overwrite of the given field.
212
- #
213
- # @param [Symbol] field The field to check.
214
- #
215
- # @return [true, false, nil] Whether the field is allowed, denied or not set.
216
- #
217
- def [](field)
218
- if @allow & self.class.bits[field] != 0
219
- true
220
- elsif @deny & self.class.bits[field] != 0
221
- false
222
- end
223
- end
224
-
225
- #
226
- # Sets the given field to the given value.
227
- #
228
- # @param [Symbol] key The field to set.
229
- # @param [Boolean] bool The value to set.
230
- #
231
- def []=(key, bool)
232
- case bool
233
- when true
234
- @allow |= self.class.bits[key]
235
- @deny &= ~self.class.bits[key]
236
- when false
237
- @allow &= ~self.class.bits[key]
238
- @deny |= self.class.bits[key]
239
- else
240
- @allow &= ~self.class.bits[key]
241
- @deny &= ~self.class.bits[key]
242
- end
243
- end
244
-
245
- #
246
- # (see Flag#method_missing)
247
- #
248
- def method_missing(method, bool = nil)
249
- if self.class.bits.key?(method)
250
- self[method]
251
- elsif self.class.bits.key?(method.to_s.delete_suffix("=").to_sym)
252
- key = method.to_s.delete_suffix("=").to_sym
253
- self[key] = bool
254
- else
255
- super
256
- end
257
- end
258
-
259
- def respond_to_missing?(method, _arg)
260
- self.class.bits.key?(method.to_s.delete_suffix("=").to_sym) ? true : super
261
- end
262
-
263
- class << self
264
- # @private
265
- attr_reader :bits
266
-
267
- #
268
- # Initializes a permission overwrite from a hash.
269
- #
270
- # @param [Hash] hash The hash to initialize the permission overwrite from.
271
- #
272
- # @return [Discorb::PermissionOverwrite] The permission overwrite.
273
- #
274
- def from_hash(hash)
275
- allow = 0
276
- deny = 0
277
- hash.filter { |k, v| self.class.bits.keys.include?(k) && [true, false].include?(v) }.each do |k, v|
278
- if v
279
- allow += self.class.bits[k]
280
- else
281
- deny += self.class.bits[k]
282
- end
283
- end
284
-
285
- new(allow, deny)
286
- end
287
- end
288
- end
289
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a permission per guild.
6
+ # ## Flag fields
7
+ #
8
+ # | Field | Value |
9
+ # |-------|-------|
10
+ # |`1 << 0`|`:create_instant_invite`|
11
+ # |`1 << 1`|`:kick_members`|
12
+ # |`1 << 2`|`:ban_members`|
13
+ # |`1 << 3`|`:administrator`|
14
+ # |`1 << 4`|`:manage_channels`|
15
+ # |`1 << 5`|`:manage_guild`|
16
+ # |`1 << 6`|`:add_reactions`|
17
+ # |`1 << 7`|`:view_audit_log`|
18
+ # |`1 << 8`|`:priority_speaker`|
19
+ # |`1 << 9`|`:stream`|
20
+ # |`1 << 10`|`:view_channel`|
21
+ # |`1 << 11`|`:send_messages`|
22
+ # |`1 << 12`|`:send_tts_messages`|
23
+ # |`1 << 13`|`:manage_messages`|
24
+ # |`1 << 14`|`:embed_links`|
25
+ # |`1 << 15`|`:attach_files`|
26
+ # |`1 << 16`|`:read_message_history`|
27
+ # |`1 << 17`|`:mention_everyone`|
28
+ # |`1 << 18`|`:use_external_emojis`|
29
+ # |`1 << 19`|`:view_guild_insights`|
30
+ # |`1 << 20`|`:connect`|
31
+ # |`1 << 21`|`:speak`|
32
+ # |`1 << 22`|`:mute_members`|
33
+ # |`1 << 23`|`:deafen_members`|
34
+ # |`1 << 24`|`:move_members`|
35
+ # |`1 << 25`|`:use_vad`|
36
+ # |`1 << 26`|`:change_nickname`|
37
+ # |`1 << 27`|`:manage_nicknames`|
38
+ # |`1 << 28`|`:manage_roles`|
39
+ # |`1 << 29`|`:manage_webhooks`|
40
+ # |`1 << 30`|`:manage_emojis`|
41
+ # |`1 << 31`|`:use_slash_commands`|
42
+ # |`1 << 32`|`:request_to_speak`|
43
+ # |`1 << 34`|`:manage_threads`|
44
+ # |`1 << 35`|`:use_public_threads`|
45
+ # |`1 << 36`|`:use_private_threads`|
46
+ #
47
+ class Permission < Flag
48
+ @bits = {
49
+ create_instant_invite: 0,
50
+ kick_members: 1,
51
+ ban_members: 2,
52
+ administrator: 3,
53
+ manage_channels: 4,
54
+ manage_guild: 5,
55
+ add_reactions: 6,
56
+ view_audit_log: 7,
57
+ priority_speaker: 8,
58
+ stream: 9,
59
+ view_channel: 10,
60
+ send_messages: 11,
61
+ send_tts_messages: 12,
62
+ manage_messages: 13,
63
+ embed_links: 14,
64
+ attach_files: 15,
65
+ read_message_history: 16,
66
+ mention_everyone: 17,
67
+ use_external_emojis: 18,
68
+ view_guild_insights: 19,
69
+ connect: 20,
70
+ speak: 21,
71
+ mute_members: 22,
72
+ deafen_members: 23,
73
+ move_members: 24,
74
+ use_vad: 25,
75
+ change_nickname: 26,
76
+ manage_nicknames: 27,
77
+ manage_roles: 28,
78
+ manage_webhooks: 29,
79
+ manage_emojis: 30,
80
+ use_slash_commands: 31,
81
+ request_to_speak: 32,
82
+ manage_threads: 34,
83
+ use_public_threads: 35,
84
+ use_private_threads: 36,
85
+ use_external_stickers: 37,
86
+ send_messages_in_threads: 38,
87
+ use_embedded_activities: 39,
88
+ moderate_members: 40
89
+ }.freeze
90
+ end
91
+
92
+ #
93
+ # Represents a permission per channel.
94
+ #
95
+ class PermissionOverwrite
96
+ # @!attribute [r] allow
97
+ # @return [Discorb::Permission] The allowed permissions.
98
+ # @!attribute [r] deny
99
+ # @return [Discorb::Permission] The denied permissions.
100
+ # @!attribute [r] allow_value
101
+ # @return [Integer] The allowed permissions as an integer.
102
+ # @!attribute [r] deny_value
103
+ # @return [Integer] The denied permissions as an integer.
104
+
105
+ @raw_bits = {
106
+ create_instant_invite: 0,
107
+ kick_members: 1,
108
+ ban_members: 2,
109
+ administrator: 3,
110
+ manage_channels: 4,
111
+ manage_guild: 5,
112
+ add_reactions: 6,
113
+ view_audit_log: 7,
114
+ priority_speaker: 8,
115
+ stream: 9,
116
+ view_channel: 10,
117
+ send_messages: 11,
118
+ send_tts_messages: 12,
119
+ manage_messages: 13,
120
+ embed_links: 14,
121
+ attach_files: 15,
122
+ read_message_history: 16,
123
+ mention_everyone: 17,
124
+ use_external_emojis: 18,
125
+ view_guild_insights: 19,
126
+ connect: 20,
127
+ speak: 21,
128
+ mute_members: 22,
129
+ deafen_members: 23,
130
+ move_members: 24,
131
+ use_vad: 25,
132
+ change_nickname: 26,
133
+ manage_nicknames: 27,
134
+ manage_roles: 28,
135
+ manage_webhooks: 29,
136
+ manage_emojis: 30,
137
+ use_slash_commands: 31,
138
+ request_to_speak: 32,
139
+ manage_threads: 34,
140
+ use_public_threads: 35,
141
+ use_private_threads: 36
142
+ }.freeze
143
+ @bits = @raw_bits.transform_values { |v| 1 << v }.freeze
144
+
145
+ #
146
+ # Initializes a new PermissionOverwrite.
147
+ # @private
148
+ #
149
+ # @param allow [Integer] The allowed permissions.
150
+ # @param deny [Integer] The denied permissions.
151
+ #
152
+ def initialize(allow, deny)
153
+ @allow = allow
154
+ @deny = deny
155
+ end
156
+
157
+ def allow
158
+ self.class.bits.keys.filter do |field|
159
+ @allow & self.class.bits[field] != 0
160
+ end
161
+ end
162
+
163
+ alias +@ allow
164
+
165
+ def deny
166
+ self.class.bits.keys.filter do |field|
167
+ @deny & self.class.bits[field] != 0
168
+ end
169
+ end
170
+
171
+ alias -@ deny
172
+
173
+ def allow_value
174
+ @allow
175
+ end
176
+
177
+ def deny_value
178
+ @deny
179
+ end
180
+
181
+ def inspect
182
+ "#<#{self.class} allow=#{allow} deny=#{deny}>"
183
+ end
184
+
185
+ #
186
+ # Converts the permission overwrite to a hash.
187
+ #
188
+ # @return [Hash] The permission overwrite as a hash.
189
+ #
190
+ def to_hash
191
+ self.class.bits.keys.to_h do |field|
192
+ [
193
+ field,
194
+ if @allow & self.class.bits[field] != 0
195
+ true
196
+ elsif @deny & self.class.bits[field] != 0
197
+ false
198
+ end
199
+ ]
200
+ end
201
+ end
202
+
203
+ #
204
+ # Union of the permission overwrites.
205
+ #
206
+ # @param [Discorb::PermissionOverwrite] other The other permission overwrite.
207
+ #
208
+ # @return [Discorb::PermissionOverwrite] The union of the permission overwrites.
209
+ #
210
+ def +(other)
211
+ result = to_hash
212
+ self.class.bits.each_key do |field|
213
+ next if other[field].nil?
214
+ result[field] = (
215
+ other[field] ||
216
+ raise(KeyError, "field #{field} not found in #{other.inspect}")
217
+ )
218
+ end
219
+ self.class.from_hash(result)
220
+ end
221
+
222
+ #
223
+ # Returns whether overwrite of the given field.
224
+ #
225
+ # @param [Symbol] field The field to check.
226
+ #
227
+ # @return [true, false, nil] Whether the field is allowed, denied or not set.
228
+ #
229
+ def [](field)
230
+ if @allow & self.class.bits[field] != 0
231
+ true
232
+ elsif @deny & self.class.bits[field] != 0
233
+ false
234
+ end
235
+ end
236
+
237
+ #
238
+ # Sets the given field to the given value.
239
+ #
240
+ # @param [Symbol] key The field to set.
241
+ # @param [Boolean] bool The value to set.
242
+ #
243
+ def []=(key, bool)
244
+ case bool
245
+ when true
246
+ @allow |= self.class.bits[key]
247
+ @deny &= ~self.class.bits[key]
248
+ when false
249
+ @allow &= ~self.class.bits[key]
250
+ @deny |= self.class.bits[key]
251
+ else
252
+ @allow &= ~self.class.bits[key]
253
+ @deny &= ~self.class.bits[key]
254
+ end
255
+ end
256
+
257
+ #
258
+ # (see Flag#method_missing)
259
+ #
260
+ def method_missing(method, bool = nil)
261
+ if self.class.bits.key?(method)
262
+ self[method]
263
+ elsif self.class.bits.key?(method.to_s.delete_suffix("=").to_sym)
264
+ key = method.to_s.delete_suffix("=").to_sym
265
+ self[key] = bool
266
+ else
267
+ super
268
+ end
269
+ end
270
+
271
+ def respond_to_missing?(method, _arg)
272
+ self.class.bits.key?(method.to_s.delete_suffix("=").to_sym) ? true : super
273
+ end
274
+
275
+ class << self
276
+ # @private
277
+ attr_reader :bits
278
+
279
+ #
280
+ # Initializes a permission overwrite from a hash.
281
+ #
282
+ # @param [Hash] hash The hash to initialize the permission overwrite from.
283
+ #
284
+ # @return [Discorb::PermissionOverwrite] The permission overwrite.
285
+ #
286
+ def from_hash(hash)
287
+ allow = 0
288
+ deny = 0
289
+ hash
290
+ .filter do |k, v|
291
+ self.class.bits.keys.include?(k) && [true, false].include?(v)
292
+ end
293
+ .each do |k, v|
294
+ if v
295
+ allow += self.class.bits[k]
296
+ else
297
+ deny += self.class.bits[k]
298
+ end
299
+ end
300
+
301
+ new(allow, deny)
302
+ end
303
+ end
304
+ end
305
+ end