swifter_enum 1.1.0 → 1.1.1
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/README.md +226 -70
- data/lib/swifter_enum/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 256304e01311b60f1cf26bc7ad5d52fb7ba625bbc6c3b4216e6af129042d3516
|
4
|
+
data.tar.gz: fd82b318f1aa43a43c87eeebb965a36515b40f23f1a4a92928ed7d2e374052d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e22b72fbbdc5a9090bc18189ea10542c08ad17fc4236067c304274c8bd5100090adf7e2eb5f94b264f5f9f1fe8b84a64c9e9bff849a24249b60d689ab53b443
|
7
|
+
data.tar.gz: 67cfb099c8c99eb3d754802841f49a144f6fcfba54cd2855dd6b3f645b0f16946870fe9f0bc1509f5ba06cedffbb92460755bf35a629156b10414a0fd3be6a21
|
data/README.md
CHANGED
@@ -1,53 +1,195 @@
|
|
1
1
|
# SwifterEnum
|
2
2
|
|
3
|
-
SwifterEnum
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
SwifterEnum brings Swift-style enums to Ruby on Rails, allowing you to encapsulate behavior within your enum types rather than scattering it throughout your application.
|
4
|
+
|
5
|
+
## Why SwifterEnum?
|
6
|
+
|
7
|
+
In Swift, enums are first-class types that can have methods, computed properties, and associated values. SwifterEnum brings this powerful pattern to Rails by replacing simple string/integer enums with proper objects that can carry their own behavior.
|
8
|
+
|
9
|
+
### Key Benefits
|
10
|
+
|
11
|
+
**1. Encapsulated Behavior** - Your enum knows how to handle itself:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# Define your enum with its behavior
|
15
|
+
class PaymentStatusEnum < SwifterEnum::Base
|
16
|
+
set_values ({
|
17
|
+
pending: 0,
|
18
|
+
processing: 10,
|
19
|
+
completed: 20,
|
20
|
+
failed: 30,
|
21
|
+
refunded: 40
|
22
|
+
})
|
23
|
+
|
24
|
+
def completed?
|
25
|
+
[:completed, :refunded].include?(value)
|
26
|
+
end
|
27
|
+
|
28
|
+
def can_refund?
|
29
|
+
value == :completed
|
30
|
+
end
|
31
|
+
|
32
|
+
def icon
|
33
|
+
case value
|
34
|
+
when :pending then "clock"
|
35
|
+
when :processing then "spinner"
|
36
|
+
when :completed then "check-circle"
|
37
|
+
when :failed then "x-circle"
|
38
|
+
when :refunded then "rotate-left"
|
11
39
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
helper method somewhere in the app
|
22
|
-
|
23
|
-
#app/helpers/controller_helper.rb
|
24
|
-
|
25
|
-
def icon_for(camera:)
|
26
|
-
...
|
40
|
+
end
|
41
|
+
|
42
|
+
def color
|
43
|
+
case value
|
44
|
+
when :pending then "gray"
|
45
|
+
when :processing then "blue"
|
46
|
+
when :completed then "green"
|
47
|
+
when :failed then "red"
|
48
|
+
when :refunded then "orange"
|
27
49
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Use it naturally in your models
|
54
|
+
order.payment_status.completed? # => true
|
55
|
+
order.payment_status.can_refund? # => true
|
56
|
+
order.payment_status.icon # => "check-circle"
|
57
|
+
order.payment_status.color # => "green"
|
58
|
+
```
|
59
|
+
|
60
|
+
**2. Type Safety** - Catch invalid values at runtime:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# Safe access with bracket notation - raises error for invalid values
|
64
|
+
status = PaymentStatusEnum[:completed] # ✓ Returns enum instance
|
65
|
+
status = PaymentStatusEnum[:invalid] # ✗ Raises ArgumentError
|
66
|
+
|
67
|
+
# Validation in models
|
68
|
+
class Order < ApplicationRecord
|
69
|
+
swifter_enum :payment_status, PaymentStatusEnum
|
70
|
+
validates :payment_status, swifter_enum: true
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
**3. Smart Enum Objects with Flexible Equality** - Returns enum instances that work naturally with symbols and strings:
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
order.payment_status # => #<PaymentStatusEnum @value=:completed>
|
78
|
+
|
79
|
+
# Flexible equality checking - all of these work:
|
80
|
+
order.payment_status == :completed # => true (symbol comparison)
|
81
|
+
order.payment_status == "completed" # => true (string comparison)
|
82
|
+
order.payment_status == other.payment_status # => true (enum instance comparison)
|
83
|
+
|
84
|
+
# Use in case statements naturally
|
85
|
+
case order.payment_status
|
86
|
+
when :pending then "Waiting for payment"
|
87
|
+
when :completed then "All done!"
|
88
|
+
when :failed then "Something went wrong"
|
89
|
+
end
|
90
|
+
|
91
|
+
# Or in arrays
|
92
|
+
[:completed, :refunded].include?(order.payment_status) # => true
|
93
|
+
```
|
94
|
+
|
95
|
+
**4. Seamless Rails Integration** - All standard Rails enum features continue to work:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
# Familiar Rails enum syntax
|
99
|
+
class Order < ApplicationRecord
|
100
|
+
swifter_enum :payment_status, PaymentStatusEnum
|
101
|
+
swifter_enum :priority, PriorityEnum
|
102
|
+
end
|
103
|
+
|
104
|
+
# Standard Rails enum features work unchanged:
|
105
|
+
order.payment_status = :processing # Set with symbol, string, or enum instance
|
106
|
+
order.payment_status = "processing" # String works too
|
107
|
+
order.payment_status = PaymentStatusEnum[:processing] # Or enum instance
|
108
|
+
order.completed! # Bang method sets and saves
|
109
|
+
order.completed? # => true (query method)
|
110
|
+
order.not_completed? # => false (negative query)
|
111
|
+
|
112
|
+
Order.completed # Scope returning all completed orders
|
113
|
+
Order.not_completed # Scope returning all non-completed orders
|
114
|
+
```
|
115
|
+
|
116
|
+
**5. Progressive Migration** - Adopt incrementally without breaking existing code:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
order.payment_status # => #<PaymentStatusEnum @value=:completed>
|
120
|
+
|
121
|
+
# Both setters work
|
122
|
+
order.payment_status = :pending # Symbol
|
123
|
+
order.payment_status = PaymentStatusEnum[:pending] # Enum instance
|
124
|
+
|
125
|
+
# Raw methods provide an 'escape hatch' to standard Rails enum handling
|
126
|
+
order.payment_status_raw # => "completed" (original Rails enum value)
|
127
|
+
Order.payment_status_raws # => {"pending"=>0, "processing"=>10, ...}
|
128
|
+
```
|
129
|
+
|
130
|
+
## Real-World Example
|
131
|
+
|
132
|
+
Consider a subscription system where enum behavior naturally belongs with the enum itself:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
class SubscriptionTierEnum < SwifterEnum::Base
|
136
|
+
set_values ({
|
137
|
+
free: 0,
|
138
|
+
basic: 10,
|
139
|
+
pro: 20,
|
140
|
+
enterprise: 30
|
141
|
+
})
|
142
|
+
|
143
|
+
def price
|
144
|
+
case value
|
145
|
+
when :free then 0
|
146
|
+
when :basic then 9.99
|
147
|
+
when :pro then 29.99
|
148
|
+
when :enterprise then 99.99
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def features
|
153
|
+
case value
|
154
|
+
when :free then ["5 projects", "Basic support"]
|
155
|
+
when :basic then ["20 projects", "Email support", "API access"]
|
156
|
+
when :pro then ["Unlimited projects", "Priority support", "Advanced API"]
|
157
|
+
when :enterprise then ["Everything in Pro", "SSO", "Dedicated support", "SLA"]
|
44
158
|
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def can_upgrade_to?(other_tier)
|
162
|
+
return false unless other_tier.is_a?(self.class)
|
163
|
+
self.class.values[other_tier.value] > self.class.values[value]
|
164
|
+
end
|
165
|
+
|
166
|
+
def badge_color
|
167
|
+
case value
|
168
|
+
when :free then "gray"
|
169
|
+
when :basic then "blue"
|
170
|
+
when :pro then "purple"
|
171
|
+
when :enterprise then "gold"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
45
175
|
|
46
|
-
|
176
|
+
# Clean, expressive code in your views and controllers
|
177
|
+
current_user.subscription_tier.price # => 29.99
|
178
|
+
current_user.subscription_tier.features # => ["Unlimited projects", ...]
|
179
|
+
current_user.subscription_tier.can_upgrade_to?(SubscriptionTierEnum[:enterprise]) # => true
|
47
180
|
|
48
|
-
|
181
|
+
# In your views
|
182
|
+
<span class="badge badge-<%= current_user.subscription_tier.badge_color %>">
|
183
|
+
<%= current_user.subscription_tier.t %>
|
184
|
+
</span>
|
185
|
+
<ul>
|
186
|
+
<% current_user.subscription_tier.features.each do |feature| %>
|
187
|
+
<li><%= feature %></li>
|
188
|
+
<% end %>
|
189
|
+
</ul>
|
190
|
+
```
|
49
191
|
|
50
|
-
|
192
|
+
This approach eliminates helper methods, reduces case statements scattered across your codebase, and keeps related logic together where it belongs.
|
51
193
|
|
52
194
|
|
53
195
|
## Installation
|
@@ -58,47 +200,61 @@ Add this line to your application's Gemfile:
|
|
58
200
|
|
59
201
|
## Usage
|
60
202
|
|
61
|
-
###
|
62
|
-
|
203
|
+
### Basic Setup
|
63
204
|
|
64
|
-
|
205
|
+
Define your enum class inheriting from `SwifterEnum::Base`:
|
65
206
|
|
66
|
-
|
207
|
+
```ruby
|
208
|
+
class CameraEnum < SwifterEnum::Base
|
209
|
+
# Using integers for database storage (most common)
|
210
|
+
set_values ({ videographer: 0, handcam: 1 })
|
67
211
|
|
68
|
-
|
212
|
+
# Or use strings for database storage (see "Using string values to store Enum" section)
|
213
|
+
# set_values [:videographer, :handcam]
|
69
214
|
|
70
|
-
|
71
|
-
|
215
|
+
def icon
|
216
|
+
case @value
|
217
|
+
when :videographer then "icons/video-camera"
|
218
|
+
when :handcam then "icons/hand-stop"
|
72
219
|
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
```
|
73
223
|
|
74
|
-
|
224
|
+
Use it in your model:
|
75
225
|
|
76
|
-
|
77
|
-
|
226
|
+
```ruby
|
227
|
+
class Video < ApplicationRecord
|
228
|
+
swifter_enum :camera, CameraEnum
|
78
229
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
230
|
+
# Optional validation
|
231
|
+
validates :camera, swifter_enum: true
|
232
|
+
end
|
233
|
+
```
|
234
|
+
|
235
|
+
### Working with Enum Values
|
88
236
|
|
89
|
-
|
237
|
+
```ruby
|
238
|
+
video = Video.first
|
90
239
|
|
91
|
-
|
92
|
-
|
93
|
-
|
240
|
+
# Getter returns an enum instance (not a string/symbol)
|
241
|
+
video.camera # => #<CameraEnum:0x000... @value=:handcam>
|
242
|
+
video.camera.value # => :handcam (access underlying symbol)
|
94
243
|
|
95
|
-
|
96
|
-
|
97
|
-
|
244
|
+
# Multiple ways to set values
|
245
|
+
video.camera = :videographer # Symbol
|
246
|
+
video.camera = "videographer" # String
|
247
|
+
video.camera = CameraEnum[:videographer] # Enum instance
|
248
|
+
video.camera = other_video.camera # Copy from another instance
|
98
249
|
|
99
|
-
|
100
|
-
|
250
|
+
# Call your custom methods
|
251
|
+
video.camera.icon # => "icons/video-camera"
|
101
252
|
|
253
|
+
# Works naturally with conditionals
|
254
|
+
if video.camera == :handcam
|
255
|
+
# Do something
|
256
|
+
end
|
257
|
+
```
|
102
258
|
|
103
259
|
### Safe Value Access with Bracket Notation
|
104
260
|
|
data/lib/swifter_enum/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swifter_enum
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Jonson
|
@@ -125,10 +125,11 @@ dependencies:
|
|
125
125
|
- - "~>"
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: '2.4'
|
128
|
-
description:
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
description: 'SwifterEnum transforms Rails enums from simple values into powerful
|
129
|
+
objects with methods, computed properties, and type safety. Your enums become smart:
|
130
|
+
payment_status.can_refund?, subscription.price, status.icon - all while maintaining
|
131
|
+
100% Rails enum compatibility. Drop-in replacement that eliminates scattered helper
|
132
|
+
methods and case statements throughout your codebase.'
|
132
133
|
email:
|
133
134
|
- rob@hobbyistsoftware.com
|
134
135
|
executables: []
|
@@ -178,5 +179,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
179
|
requirements: []
|
179
180
|
rubygems_version: 3.6.8
|
180
181
|
specification_version: 4
|
181
|
-
summary:
|
182
|
+
summary: Swift-style enums for Rails that encapsulate behavior within your enum types
|
182
183
|
test_files: []
|