activerecord-bitwise 0.10.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.
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/bitwise'
@@ -0,0 +1,207 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ begin
5
+ require 'tapioca/dsl'
6
+ rescue LoadError
7
+ # Namespace for Tapioca integration.
8
+ module Tapioca
9
+ # Namespace for Tapioca DSL.
10
+ module Dsl
11
+ # Stub class for Compiler under environments where Tapioca is not loaded.
12
+ class Compiler
13
+ extend T::Sig
14
+
15
+ # The model constant being compiled.
16
+ # @return [T.untyped]
17
+ sig { returns(T.untyped) }
18
+ attr_reader :constant
19
+
20
+ # The root node of the generated RBI tree.
21
+ # @return [T.untyped]
22
+ sig { returns(T.untyped) }
23
+ attr_reader :root
24
+
25
+ # Initializes a new compiler.
26
+ # @param constant [T.untyped]
27
+ sig { params(constant: T.untyped).void }
28
+ def initialize(constant)
29
+ @constant = T.let(constant, T.untyped)
30
+ @root = T.let(nil, T.untyped)
31
+ end
32
+
33
+ # Stub for type member definition.
34
+ # @param args [T.untyped]
35
+ # Sorbet's runtime signature verification requires the block argument to be named in the method definition
36
+ # (i.e. matching the `blk` name in `sig { params(blk: ...) }`) and raises `RuntimeError` if anonymous `&` is used.
37
+ # rubocop:disable Naming/BlockForwarding
38
+ sig { params(args: T.untyped, blk: T.nilable(T.proc.returns(T.untyped))).returns(T.untyped) }
39
+ def self.type_member(*args, &blk)
40
+ # Stub for environments without Tapioca
41
+ end
42
+ # rubocop:enable Naming/BlockForwarding
43
+
44
+ # Returns descendants of a class.
45
+ # @param klass [T.untyped]
46
+ # @return [T::Array[T.untyped]]
47
+ sig { params(klass: T.untyped).returns(T::Array[T.untyped]) }
48
+ def self.descendants_of(klass)
49
+ ObjectSpace.each_object(Class).select { |c| c < klass }
50
+ end
51
+
52
+ # Stub for gathering constants.
53
+ # @return [T.untyped]
54
+ sig { returns(T.untyped) }
55
+ def self.gather_constants
56
+ # Stub for override verification
57
+ end
58
+
59
+ # Stub for decorating model RBI.
60
+ # @return [void]
61
+ sig { void }
62
+ def decorate
63
+ # Stub for override verification
64
+ end
65
+
66
+ # Stub for creating method parameter.
67
+ # @param name [String]
68
+ # @param type [String]
69
+ sig { params(name: String, type: String).returns(T.untyped) }
70
+ def create_param(name, type:)
71
+ # Stub
72
+ end
73
+
74
+ # Stub for creating method rest parameter.
75
+ # @param name [String]
76
+ # @param type [String]
77
+ sig { params(name: String, type: String).returns(T.untyped) }
78
+ def create_rest_param(name, type:)
79
+ # Stub
80
+ end
81
+
82
+ # Stub for creating method keyword parameter.
83
+ # @param name [String]
84
+ # @param type [String]
85
+ sig { params(name: String, type: String).returns(T.untyped) }
86
+ def create_kw_param(name, type:)
87
+ # Stub
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # Namespace for Tapioca integration.
95
+ module Tapioca
96
+ # Namespace for Tapioca DSL.
97
+ module Dsl
98
+ # Namespace for specific Tapioca DSL compilers.
99
+ module Compilers
100
+ # Tapioca DSL Compiler for Sorbet static analysis of ActiveRecord::Bitwise attributes and scopes.
101
+ class ActiveRecordBitwise < Compiler
102
+ extend T::Sig
103
+
104
+ # The fixed constant type that this compiler is responsible for.
105
+ ConstantType = type_member { { fixed: T.class_of(ActiveRecord::Base) } }
106
+
107
+ sig { override.returns(T::Enumerable[T::Module[T.anything]]) }
108
+ def self.gather_constants
109
+ descendants_of(ActiveRecord::Base).select do |klass|
110
+ klass.respond_to?(:bitwise_definitions) && T.unsafe(klass).bitwise_definitions.any?
111
+ end
112
+ end
113
+
114
+ sig { override.void }
115
+ def decorate
116
+ T.unsafe(root).create_path(constant) do |model|
117
+ model.create_method('bitwise_schema',
118
+ parameters: [create_param('col', type: 'T.any(Symbol, String)')],
119
+ return_type: 'T.nilable(T::Hash[Symbol, Integer])',
120
+ class_method: true)
121
+ end
122
+
123
+ T.unsafe(constant).bitwise_definitions.each do |column_name, config|
124
+ T.unsafe(root).create_path(constant) do |model|
125
+ model.create_method(column_name.to_s, return_type: 'T::Array[T.any(Symbol, String)]')
126
+ model.create_method("#{column_name}=",
127
+ parameters: [create_param('val', type: 'T::Array[T.any(Symbol, String)]')], return_type: 'T::Array[T.any(Symbol, String)]')
128
+
129
+ prefix = config[:prefix]
130
+ suffix = config[:suffix]
131
+ mapping = config[:mapping]
132
+
133
+ prefix_str = case prefix
134
+ when true then "#{T.unsafe(column_name.to_s).singularize}_"
135
+ when Symbol, String then "#{prefix}_"
136
+ else ''
137
+ end
138
+
139
+ suffix_str = case suffix
140
+ when true then "_#{T.unsafe(column_name.to_s).singularize}"
141
+ when Symbol, String then "_#{suffix}"
142
+ else ''
143
+ end
144
+
145
+ mapping.each_key do |key|
146
+ method_name = "#{prefix_str}#{key}#{suffix_str}"
147
+ model.create_method("#{method_name}?", return_type: 'T::Boolean')
148
+ model.create_method("#{method_name}=", parameters: [create_param('val', type: 'T::Boolean')],
149
+ return_type: 'T::Boolean')
150
+ model.create_method("#{method_name}!", return_type: 'TrueClass')
151
+ end
152
+
153
+ # Instance-level atomic methods
154
+ singular_col = T.unsafe(column_name.to_s).singularize
155
+ model.create_method("add_#{singular_col}!",
156
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
157
+ return_type: 'void')
158
+ model.create_method("add_#{column_name}!",
159
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
160
+ return_type: 'void')
161
+ model.create_method("remove_#{singular_col}!",
162
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
163
+ return_type: 'void')
164
+ model.create_method("remove_#{column_name}!",
165
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
166
+ return_type: 'void')
167
+
168
+ # Class-level atomic methods
169
+ model.create_method("add_#{column_name}!",
170
+ parameters: [
171
+ create_rest_param('values', type: 'T.any(Symbol, String)'),
172
+ create_kw_param('records', type: 'T.untyped')
173
+ ],
174
+ return_type: 'void',
175
+ class_method: true)
176
+ model.create_method("remove_#{column_name}!",
177
+ parameters: [
178
+ create_rest_param('values', type: 'T.any(Symbol, String)'),
179
+ create_kw_param('records', type: 'T.untyped')
180
+ ],
181
+ return_type: 'void',
182
+ class_method: true)
183
+
184
+ # Scopes
185
+ model.create_method("with_#{column_name}",
186
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
187
+ return_type: 'ActiveRecord::Relation',
188
+ class_method: true)
189
+ model.create_method("with_any_#{column_name}",
190
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
191
+ return_type: 'ActiveRecord::Relation',
192
+ class_method: true)
193
+ model.create_method("with_exact_#{column_name}",
194
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
195
+ return_type: 'ActiveRecord::Relation',
196
+ class_method: true)
197
+ model.create_method("without_#{column_name}",
198
+ parameters: [create_rest_param('values', type: 'T.any(Symbol, String)')],
199
+ return_type: 'ActiveRecord::Relation',
200
+ class_method: true)
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,278 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-bitwise
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.0
5
+ platform: ruby
6
+ authors:
7
+ - VitaliiLazebnyi
8
+ bindir: exe
9
+ cert_chain:
10
+ - |
11
+ -----BEGIN CERTIFICATE-----
12
+ MIIEOTCCAqGgAwIBAgIUBONmsFo7fxLGkUHsKe65onH+5ogwDQYJKoZIhvcNAQEL
13
+ BQAwLDEqMCgGA1UEAwwhdml0YWxpaS5sYXplYm55aS5naXRodWJAZ21haWwuY29t
14
+ MB4XDTI2MDQxNTEzNTMyOVoXDTM2MDQxMjEzNTMyOVowLDEqMCgGA1UEAwwhdml0
15
+ YWxpaS5sYXplYm55aS5naXRodWJAZ21haWwuY29tMIIBojANBgkqhkiG9w0BAQEF
16
+ AAOCAY8AMIIBigKCAYEA5zdezJE+Zrsk9j53/IxBfRoaqvLcPvrcfl+EaEwWhIkV
17
+ 0+08GtgS9N7VpB8cgaH2rkLJPjHIetsN/g5GMkDRsbJNXMrPVhxe1e1lI/r6j0Tm
18
+ JD0PaU4r8VzitxkqY9BBmSI8GjDjAfrT1u5jSXH1iAtKUoq5F116uYrxbgiDpvqa
19
+ kUQYcTf+6cZaPlF4KKhULnhKqs8u/NxyH4vPZyxEfg/gA4bODvcjW1A6d59BTiLV
20
+ yrJPebwU+F+URb8aoQ4AGvPKFiG1Y1fxRHuPrOpyymFnBnjwgMyQkNHtzTeEriV9
21
+ z1BUb10Pb/pjLBCrOvnStTPmcm1GE8HL2psYvlLvBlYqq3gzpQPBBKE3Jefa7ilC
22
+ cYsBYOGpynpA9uu9cXKa4jtpPDGQ7Qrpnk9gHy/0xfbgLdAkRCoZJeR7wDL/1xmm
23
+ nXwcUOLSOBj1Y4P9M+uQSQUZFTAaLbwyaBfE1gvVjwbTv3+rNP1ck1hACt+numGG
24
+ m7R6MF+Hmh8pNnDBYpBNAgMBAAGjUzBRMB0GA1UdDgQWBBRbuaz1EhdG6T4KIeWr
25
+ ac8LULxO9zAfBgNVHSMEGDAWgBRbuaz1EhdG6T4KIeWrac8LULxO9zAPBgNVHRMB
26
+ Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBgQBgfGTDIMxlm6o8o7dzCR0HosRm
27
+ DSeUrx46EG1knTEqO05CooEHW98hrHa1/EwzkPaH1KhjjserQb6VtczMnySlfySu
28
+ HbKWAIaqzlpf8zaE5tCiAKgFKr77b2XB7xKt25p/Vf/Kn/RLm3+sYQ2izzzMimei
29
+ tBHo29cLV9bB/5HHFDwjrtdC5a0HJHiir0w4MCSDDGtnsKird4RKD2xESpoVjiNg
30
+ L9nEGk25YDeIfKn8UtxduMv53T86CiBSsDcEb6oVjNiMOA0HFucwFKX+Vy5u0/qx
31
+ ZRoLbZiCkTTGyNkBh4o6RCCTn37Lj98FBxYMbAHLNhEcKnAGxB7XP/CYsV4+QHOy
32
+ h0PctylhIvm24QeKgIWJUWamFPfqdvlP660T4umxl2wMqvNpWmGMmGTMCraoKwxl
33
+ zpp6uA15MXgTU7CxGivRgUKM64TqBMZKkOJcCtPkruSobxiR8cROrBNTqEbrmedM
34
+ 26EUEoxwDzfSzHU2SKz5pMR+8DClMUKB1rctg68=
35
+ -----END CERTIFICATE-----
36
+ date: 1980-01-02 00:00:00.000000000 Z
37
+ dependencies:
38
+ - !ruby/object:Gem::Dependency
39
+ name: activerecord
40
+ requirement: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '5.0'
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '5.0'
52
+ - !ruby/object:Gem::Dependency
53
+ name: sorbet-runtime
54
+ requirement: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '0.6'
59
+ type: :runtime
60
+ prerelease: false
61
+ version_requirements: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '0.6'
66
+ - !ruby/object:Gem::Dependency
67
+ name: rspec
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '3.12'
73
+ type: :development
74
+ prerelease: false
75
+ version_requirements: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '3.12'
80
+ - !ruby/object:Gem::Dependency
81
+ name: rubocop
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: '1.50'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '1.50'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rubocop-md
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - "~>"
99
+ - !ruby/object:Gem::Version
100
+ version: '1.2'
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: '1.2'
108
+ - !ruby/object:Gem::Dependency
109
+ name: rubocop-performance
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '1.21'
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: '1.21'
122
+ - !ruby/object:Gem::Dependency
123
+ name: rubocop-rspec
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: '3.0'
129
+ type: :development
130
+ prerelease: false
131
+ version_requirements: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '3.0'
136
+ - !ruby/object:Gem::Dependency
137
+ name: rubocop-thread_safety
138
+ requirement: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '0.6'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '0.6'
150
+ - !ruby/object:Gem::Dependency
151
+ name: simplecov
152
+ requirement: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - "~>"
155
+ - !ruby/object:Gem::Version
156
+ version: '0.22'
157
+ type: :development
158
+ prerelease: false
159
+ version_requirements: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - "~>"
162
+ - !ruby/object:Gem::Version
163
+ version: '0.22'
164
+ - !ruby/object:Gem::Dependency
165
+ name: simplecov-ai
166
+ requirement: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - "~>"
169
+ - !ruby/object:Gem::Version
170
+ version: '0.10'
171
+ type: :development
172
+ prerelease: false
173
+ version_requirements: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - "~>"
176
+ - !ruby/object:Gem::Version
177
+ version: '0.10'
178
+ - !ruby/object:Gem::Dependency
179
+ name: sorbet
180
+ requirement: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - "~>"
183
+ - !ruby/object:Gem::Version
184
+ version: '0.5'
185
+ type: :development
186
+ prerelease: false
187
+ version_requirements: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - "~>"
190
+ - !ruby/object:Gem::Version
191
+ version: '0.5'
192
+ - !ruby/object:Gem::Dependency
193
+ name: sqlite3
194
+ requirement: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - "~>"
197
+ - !ruby/object:Gem::Version
198
+ version: '2.1'
199
+ type: :development
200
+ prerelease: false
201
+ version_requirements: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - "~>"
204
+ - !ruby/object:Gem::Version
205
+ version: '2.1'
206
+ - !ruby/object:Gem::Dependency
207
+ name: yard
208
+ requirement: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - "~>"
211
+ - !ruby/object:Gem::Version
212
+ version: '0.9'
213
+ type: :development
214
+ prerelease: false
215
+ version_requirements: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - "~>"
218
+ - !ruby/object:Gem::Version
219
+ version: '0.9'
220
+ - !ruby/object:Gem::Dependency
221
+ name: yard-sorbet
222
+ requirement: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - "~>"
225
+ - !ruby/object:Gem::Version
226
+ version: '0.6'
227
+ type: :development
228
+ prerelease: false
229
+ version_requirements: !ruby/object:Gem::Requirement
230
+ requirements:
231
+ - - "~>"
232
+ - !ruby/object:Gem::Version
233
+ version: '0.6'
234
+ description: A Ruby gem that extends ActiveRecord to support bitwise enum mapping,
235
+ allowing multiple states to be saved in a single database column.
236
+ email:
237
+ - vitalii.lazebnyi.github@gmail.com
238
+ executables: []
239
+ extensions: []
240
+ extra_rdoc_files: []
241
+ files:
242
+ - BUGS.md
243
+ - CHANGELOG.md
244
+ - LICENSE.txt
245
+ - README.md
246
+ - REQUIREMENTS.md
247
+ - certs/activerecord-bitwise-public_cert.pem
248
+ - lib/active_record/bitwise.rb
249
+ - lib/active_record/bitwise/bitwise_validator.rb
250
+ - lib/active_record/bitwise/version.rb
251
+ - lib/activerecord-bitwise.rb
252
+ - lib/tapioca/dsl/compilers/activerecord_bitwise.rb
253
+ homepage: https://github.com/VitaliiLazebnyi/activerecord-bitwise
254
+ licenses:
255
+ - MIT
256
+ metadata:
257
+ allowed_push_host: https://rubygems.org
258
+ source_code_uri: https://github.com/VitaliiLazebnyi/activerecord-bitwise
259
+ changelog_uri: https://github.com/VitaliiLazebnyi/activerecord-bitwise/blob/main/CHANGELOG.md
260
+ rubygems_mfa_required: 'true'
261
+ rdoc_options: []
262
+ require_paths:
263
+ - lib
264
+ required_ruby_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: 3.2.0
269
+ required_rubygems_version: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: '0'
274
+ requirements: []
275
+ rubygems_version: 4.0.10
276
+ specification_version: 4
277
+ summary: Store multiple boolean values as a single integer bitmask.
278
+ test_files: []
metadata.gz.sig ADDED
Binary file