bitmask_enum 1.0.0 → 1.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +55 -1
- data/lib/bitmask_enum/attribute.rb +45 -11
- data/lib/bitmask_enum/eval_scripts.rb +28 -1
- data/lib/bitmask_enum/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ca2abf599d5126367ff0a605da44b150e39d475a2e715fb7a1c424edc54a31ea
|
|
4
|
+
data.tar.gz: f67516fe2b686f8d92044ad745be0189c6cb71af86ef2689c9b3785b16a7e99a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a2261aa059b461ce5ed1083a66fd8e9173c3f4fd58241e9beb116a1ac0848077f347370e8468d8012bf1555153a1f2fbaa293edd7944f392ed6391e03a19b7dd
|
|
7
|
+
data.tar.gz: 7ab5c0cd95db21e8e36aa744d46e61efc943ad465e6912898843fbf91e641d265b7bce6ecd857e8575b93b7678379d00813923b14f8ddff97c1ebd27c9d7d8b1
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -37,3 +37,9 @@ Add YARD docs.
|
|
|
37
37
|
Standardize output to symbols.
|
|
38
38
|
Add validation of the attribute - less_than: 1 << flags.size
|
|
39
39
|
Add max ActiveRecord version to protect against future breaking releases
|
|
40
|
+
|
|
41
|
+
# 1.1.0 : 2022-08-30
|
|
42
|
+
|
|
43
|
+
Add dynamic scopes for any of provided flags enabled or disabled.
|
|
44
|
+
Add dynamic scopes for all of provided flags enabled or disabled.
|
|
45
|
+
Correct and update some documentation.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -10,6 +10,8 @@ Supporting Ruby 2.4+ and Rails 4.2+.
|
|
|
10
10
|
|
|
11
11
|
Credit is due to Joel Moss' gem [bitmask_attributes](https://github.com/joelmoss/bitmask_attributes). I came across it while considering if I should write a gem for this. It's great work and some elements of it inspired this gem, I just had my own thoughts about how I'd like the gem to operate, and wanted some more end-to-end experience on gem production so I decided to create this rather than pick up the torch on that repo.
|
|
12
12
|
|
|
13
|
+
This gem attempts to improve performance by precomputing the integer values for the enum rather than using bitwise operations in the SQL.
|
|
14
|
+
|
|
13
15
|
## Installation
|
|
14
16
|
|
|
15
17
|
Add this line to your application's Gemfile:
|
|
@@ -28,6 +30,8 @@ Or install it yourself as:
|
|
|
28
30
|
|
|
29
31
|
## Usage
|
|
30
32
|
|
|
33
|
+
[RubyDocs for BitmaskEnum](https://www.rubydoc.info/github/lucygilbert/bitmask_enum/master)
|
|
34
|
+
|
|
31
35
|
In the model, the bitmask enum is added in a similar way to enums. Given an integer attribute called `attribs`, flags of `flag` and `flag2`, adding the `flag_prefix` option with the value `type`, the following line would be used:
|
|
32
36
|
|
|
33
37
|
```ruby
|
|
@@ -129,7 +133,9 @@ The method returns an array of all enabled flags on the instance. The items will
|
|
|
129
133
|
|
|
130
134
|
### `{attribute}=` (_Override_)
|
|
131
135
|
|
|
132
|
-
**
|
|
136
|
+
**Params**
|
|
137
|
+
|
|
138
|
+
- value [Integer, Symbol, String, Array\<Symbol, String\>] - An integer, a defined flag or array of defined flags
|
|
133
139
|
|
|
134
140
|
This method will be created once on the instance.
|
|
135
141
|
|
|
@@ -163,6 +169,54 @@ The method is a scope of all records for which the flag is disabled.
|
|
|
163
169
|
|
|
164
170
|
**Return value:** `ActiveRecord::Relation` - a collection of all records for which the flag is disabled.
|
|
165
171
|
|
|
172
|
+
### `any_{attribute}_enabled`
|
|
173
|
+
|
|
174
|
+
**Params**
|
|
175
|
+
|
|
176
|
+
- flags [Symbol, String, Array\<Symbol, String\>] - A defined flag or array of defined flags
|
|
177
|
+
|
|
178
|
+
This method will be created once on the class.
|
|
179
|
+
|
|
180
|
+
The method is a scope of all records for which any of the provided flags are enabled.
|
|
181
|
+
|
|
182
|
+
**Return value:** `ActiveRecord::Relation` - a collection of all records for which the flag is enabled.
|
|
183
|
+
|
|
184
|
+
### `any_{attribute}_disabled`
|
|
185
|
+
|
|
186
|
+
**Params**
|
|
187
|
+
|
|
188
|
+
- flags [Symbol, String, Array\<Symbol, String\>] - A defined flag or array of defined flags
|
|
189
|
+
|
|
190
|
+
This method will be created once on the class.
|
|
191
|
+
|
|
192
|
+
The method is a scope of all records for which any of the provided flags are disabled.
|
|
193
|
+
|
|
194
|
+
**Return value:** `ActiveRecord::Relation` - a collection of all records for which the flag is disabled.
|
|
195
|
+
|
|
196
|
+
### `all_{attribute}_enabled`
|
|
197
|
+
|
|
198
|
+
**Params**
|
|
199
|
+
|
|
200
|
+
- flags [Symbol, String, Array\<Symbol, String\>] - A defined flag or array of defined flags
|
|
201
|
+
|
|
202
|
+
This method will be created once on the class.
|
|
203
|
+
|
|
204
|
+
The method is a scope of all records for which all of the provided flags are enabled.
|
|
205
|
+
|
|
206
|
+
**Return value:** `ActiveRecord::Relation` - a collection of all records for which the flag is enabled.
|
|
207
|
+
|
|
208
|
+
### `all_{attribute}_disabled`
|
|
209
|
+
|
|
210
|
+
**Params**
|
|
211
|
+
|
|
212
|
+
- flags [Symbol, String, Array\<Symbol, String\>] - A defined flag or array of defined flags
|
|
213
|
+
|
|
214
|
+
This method will be created once on the class.
|
|
215
|
+
|
|
216
|
+
The method is a scope of all records for which all of the provided flags are disabled.
|
|
217
|
+
|
|
218
|
+
**Return value:** `ActiveRecord::Relation` - a collection of all records for which the flag is disabled.
|
|
219
|
+
|
|
166
220
|
### `{attribute}`
|
|
167
221
|
|
|
168
222
|
**No params**
|
|
@@ -30,6 +30,10 @@ module BitmaskEnum
|
|
|
30
30
|
flag_getter_method
|
|
31
31
|
flag_setter_method
|
|
32
32
|
|
|
33
|
+
dynamic_any_enabled_scope
|
|
34
|
+
dynamic_any_disabled_scope
|
|
35
|
+
dynamic_all_enabled_scope
|
|
36
|
+
dynamic_all_disabled_scope
|
|
33
37
|
class_flag_values_method
|
|
34
38
|
end
|
|
35
39
|
|
|
@@ -45,8 +49,8 @@ module BitmaskEnum
|
|
|
45
49
|
flag_on_method(flag_label, flag_index)
|
|
46
50
|
flag_off_method(flag_label, flag_index)
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
flag_enabled_scope(flag_label, flag_index)
|
|
53
|
+
flag_disabled_scope(flag_label, flag_index)
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
def flag_check_method(flag_label, flag_index)
|
|
@@ -80,25 +84,55 @@ module BitmaskEnum
|
|
|
80
84
|
@model.class_eval EvalScripts.flag_method(method_name, method_code), __FILE__, __LINE__
|
|
81
85
|
end
|
|
82
86
|
|
|
83
|
-
def
|
|
84
|
-
|
|
87
|
+
def flag_enabled_scope(flag_label, flag_index)
|
|
88
|
+
flag_scope("#{flag_label}_enabled", :on, flag_index)
|
|
85
89
|
end
|
|
86
90
|
|
|
87
|
-
def
|
|
88
|
-
|
|
91
|
+
def flag_disabled_scope(flag_label, flag_index)
|
|
92
|
+
flag_scope("#{flag_label}_disabled", :off, flag_index)
|
|
89
93
|
end
|
|
90
94
|
|
|
91
|
-
def
|
|
92
|
-
|
|
93
|
-
values_for_bitmask = (0...(1 << @flags.size)).select { |x| (x & (1 << flag_index)).send(comparator, 0) }
|
|
94
|
-
|
|
95
|
-
values_for_bitmask = @nil_handler.in_array(values_for_bitmask) if setting == :off
|
|
95
|
+
def flag_scope(scope_name, setting, flag_index)
|
|
96
|
+
values_for_bitmask = values_for_flag_bitmask(setting, flag_index)
|
|
96
97
|
|
|
97
98
|
@conflict_checker.check_class_method!(scope_name)
|
|
98
99
|
|
|
99
100
|
@model.class_eval EvalScripts.flag_scope(scope_name, @attribute, values_for_bitmask), __FILE__, __LINE__
|
|
100
101
|
end
|
|
101
102
|
|
|
103
|
+
def dynamic_any_enabled_scope
|
|
104
|
+
dynamic_scope("any_#{@attribute}_enabled", :on, '|')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def dynamic_any_disabled_scope
|
|
108
|
+
dynamic_scope("any_#{@attribute}_disabled", :off, '|')
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def dynamic_all_enabled_scope
|
|
112
|
+
dynamic_scope("all_#{@attribute}_enabled", :on, '&')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def dynamic_all_disabled_scope
|
|
116
|
+
dynamic_scope("all_#{@attribute}_disabled", :off, '&')
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def dynamic_scope(scope_name, setting, bitwise_operator)
|
|
120
|
+
flags_and_values = @flags.each_with_index.map do |flag, flag_index|
|
|
121
|
+
[flag, values_for_flag_bitmask(setting, flag_index)]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
@model.class_eval EvalScripts.dynamic_scope(
|
|
125
|
+
scope_name, @attribute, flags_and_values, bitwise_operator
|
|
126
|
+
), __FILE__, __LINE__ - 2
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def values_for_flag_bitmask(setting, flag_index)
|
|
130
|
+
comparator = setting == :on ? :> : :==
|
|
131
|
+
values_for_bitmask = (0...(1 << @flags.size)).select { |x| (x & (1 << flag_index)).send(comparator, 0) }
|
|
132
|
+
values_for_bitmask = @nil_handler.in_array(values_for_bitmask) if setting == :off
|
|
133
|
+
values_for_bitmask
|
|
134
|
+
end
|
|
135
|
+
|
|
102
136
|
def flag_settings_hash_method
|
|
103
137
|
method_name = "#{@attribute}_settings"
|
|
104
138
|
|
|
@@ -33,7 +33,7 @@ module BitmaskEnum
|
|
|
33
33
|
# Code for methods scoping by flag: `.flag_enabled`, `.flag_disabled`
|
|
34
34
|
# @param scope_name [String] Name of the scope
|
|
35
35
|
# @param attribute [String] Name of the attribute
|
|
36
|
-
# @param values_for_bitmask [Array] Array of integers for which the flag would be disabled
|
|
36
|
+
# @param values_for_bitmask [Array] Array of integers for which the flag would be enabled/disabled
|
|
37
37
|
# @return [String] Code string to be evaled
|
|
38
38
|
def flag_scope(scope_name, attribute, values_for_bitmask)
|
|
39
39
|
%(
|
|
@@ -43,6 +43,33 @@ module BitmaskEnum
|
|
|
43
43
|
)
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
# Code for methods dynamically scoping by flags: `.attribs_enabled`, `.attribs_disabled`
|
|
47
|
+
# @param scope_name [String] Name of the scope
|
|
48
|
+
# @param attribute [String] Name of the attribute
|
|
49
|
+
# @param flags_and_values [Array] Array of arrays, first being the flag, second being the enum values for the flag
|
|
50
|
+
# @param bitwise_operator [String] Bitwise operator used to combine the enum value arrays
|
|
51
|
+
# @return [String] Code string to be evaled
|
|
52
|
+
def dynamic_scope(scope_name, attribute, flags_and_values, bitwise_operator)
|
|
53
|
+
%(
|
|
54
|
+
scope :#{scope_name}, ->(flags) do # scope :attribs_disabled, ->(flags) do
|
|
55
|
+
enum_values = { # enum_values = {
|
|
56
|
+
#{flags_and_values.map { |f, v| "#{f}: #{v}" }.join(', ')} # flag: [1,3], flag2: [2]
|
|
57
|
+
} # }
|
|
58
|
+
#
|
|
59
|
+
where('#{attribute}' => Array(flags).map do |flag| # where('attribs' => Array(flags).map do |flag|
|
|
60
|
+
flag_values = enum_values[flag.to_sym] # flag_values = enum_values[flag.to_sym]
|
|
61
|
+
if flag_values.nil? # if flag_index.nil?
|
|
62
|
+
raise( # raise(
|
|
63
|
+
ArgumentError, # ArgumentError,
|
|
64
|
+
"Invalid flag \#{flag} for #{attribute}" # "Invalid flag \#{flag} for attribs"
|
|
65
|
+
) # )
|
|
66
|
+
end # end
|
|
67
|
+
flag_values # flag_values
|
|
68
|
+
end.reduce(&:#{bitwise_operator})) # end.map(&:|))
|
|
69
|
+
end # end
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
|
|
46
73
|
# Code for method returning hash of flags with their boolean setting: `#attribs_settings`
|
|
47
74
|
# @param method_name [String] Name of the method
|
|
48
75
|
# @param flag_hash_contents [String] Contents of the hash which provides the flag settings
|
data/lib/bitmask_enum/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bitmask_enum
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lucy Gilbert
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-08-
|
|
11
|
+
date: 2022-08-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|