discorb 0.18.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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