nummy 0.1.0 → 0.3.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/CHANGELOG.md +80 -0
- data/README.md +54 -2
- data/lib/nummy/enum.rb +75 -0
- data/lib/nummy/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83fe6928d06ebd4ba649eaa37ad3278366e2322a99fe56a7efdfed228b971841
|
4
|
+
data.tar.gz: 7116e7d5febca95ae52544bcbc42a4fd99e895ca8e60ef9cd7e3444e6dae8719
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d4bb886ad7d5187aca88391c1e9366a82b4bdb08e435cb5567951a5e2a5e5d230ef5f06cdae0bd5b104c8a62d00e41c437969cf9b9b4a4cf7d5eb41e73dd4ac
|
7
|
+
data.tar.gz: dc40fbde79187708d1006bd80475b114f98f8de238faaae8bd4a9b620f5557df06c3d960123e237267041370f59baee13d42e1f4389e97e3394e68fe6e383cfc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,85 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.0] - 2024-01-04
|
4
|
+
|
5
|
+
- **Adds additional flexibility to `Nummy::Enum.to_attribute` (#2)
|
6
|
+
|
7
|
+
This release teaches a few new tricks to `Nummy::Enum.to_attribute`:
|
8
|
+
|
9
|
+
- it allows passing a block to fully customize how keys are transformed
|
10
|
+
|
11
|
+
- it looks for `String#underscore` rather than calling into `ActiveSupport::Inflector.underscore` directly, which means that users can bring their own monkey patch if they want to.
|
12
|
+
|
13
|
+
- it falls back to `Symbol#downcase` if `String#underscore` is not available. If the constants are defined using `SCREAMING_SNAKE_CASE`, this will generally have the same result as calling `String#underscore`, but without requiring ActiveSupport.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class ShippingStatus < Nummy::Enum
|
17
|
+
IN_TRANSIT = auto
|
18
|
+
OUT_FOR_DELIVERY = auto
|
19
|
+
DELIVERED = auto
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
# Without ActiveSupport
|
25
|
+
|
26
|
+
ShippingStatus.to_attribute
|
27
|
+
# v0.2.0 (❌)
|
28
|
+
# => nummy/lib/nummy/enum.rb:379:in `block in to_attribute': uninitialized constant ActiveSupport (NameError)
|
29
|
+
#
|
30
|
+
# ::ActiveSupport::Inflector.underscore(key).to_sym
|
31
|
+
# ^^^^^^^^^^^^^^^
|
32
|
+
|
33
|
+
# v0.3.0 (✅)
|
34
|
+
# => {:in_transit=>0, :out_for_delivery=>1, :delivered=>2}
|
35
|
+
```
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
# With ActiveSupport
|
39
|
+
require "active_support/core_ext/string/inflections"
|
40
|
+
|
41
|
+
ShippingStatus.to_attribute
|
42
|
+
# => {:in_transit=>0, :out_for_delivery=>1, :delivered=>2}
|
43
|
+
|
44
|
+
ShippingStatus.to_attribute { |key| key.to_s.underscore.camelize.to_sym }
|
45
|
+
# => {:InTransit=>0, :OutForDelivery=>1, :Delivered=>2}
|
46
|
+
```
|
47
|
+
|
48
|
+
- **Adds JSON serialization support (#3)**
|
49
|
+
|
50
|
+
This release adds two methods to `Nummy::Enum`: `.as_json` and `.to_json`. These methods allow you to serialize an enum to JSON.
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
class Status < Nummy::Enum
|
54
|
+
ACTIVE = auto
|
55
|
+
ARCHIVED = auto
|
56
|
+
end
|
57
|
+
|
58
|
+
Status.as_json
|
59
|
+
# => {"ACTIVE" => 0, "ARCHIVED" => 1}
|
60
|
+
|
61
|
+
Status.to_json
|
62
|
+
# => "{\"ACTIVE\":0,\"ARCHIVED\":1}
|
63
|
+
```
|
64
|
+
|
65
|
+
## [0.2.0] - 2024-01-04
|
66
|
+
|
67
|
+
- Add `Nummy::Enum.to_attribute` (#1), which converts the enum to a hash that can be passed as the values of an `ActiveRecord::Enum`:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class Conversation < ActiveRecord::Base
|
71
|
+
class Status < Nummy::Enum
|
72
|
+
ACTIVE = auto
|
73
|
+
ARCHIVED = auto
|
74
|
+
end
|
75
|
+
|
76
|
+
enum :status, Status.to_attribute
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
> [!IMPORTANT]
|
81
|
+
> The conversion requires that `ActiveRecord::Inflector` is defined, but `nummy` does not depend on `ActiveRecord` directly. If you are using `nummy` in a non-Rails environment, you will need to require `ActiveRecord::Inflector` yourself.
|
82
|
+
|
3
83
|
## [0.1.0] - 2024-01-04
|
4
84
|
|
5
85
|
- Initial release
|
data/README.md
CHANGED
@@ -14,13 +14,13 @@ constants in a module, and iterating over the members of data classes.
|
|
14
14
|
Install the gem and add to the application's Gemfile by executing:
|
15
15
|
|
16
16
|
```console
|
17
|
-
bundle add
|
17
|
+
bundle add nummy
|
18
18
|
```
|
19
19
|
|
20
20
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
21
21
|
|
22
22
|
```console
|
23
|
-
gem install
|
23
|
+
gem install nummy
|
24
24
|
```
|
25
25
|
|
26
26
|
## Usage
|
@@ -146,6 +146,58 @@ end
|
|
146
146
|
> [!TIP]
|
147
147
|
> `Nummy::Enum` extends `Enumerable` and iterates over the _values_ of the enum, so you have access to things like `.include?(value)`, `.any?`, and `.find`.
|
148
148
|
|
149
|
+
#### Rails / ActiveRecord integration
|
150
|
+
|
151
|
+
To use nummy enums as ActiveRecord enums, you can use the `.to_attribute` method, which converts the keys to `snake_case` by default:
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
class Conversation < ActiveRecord::Base
|
155
|
+
class Status < Nummy::Enum
|
156
|
+
ACTIVE = auto
|
157
|
+
ARCHIVED = auto
|
158
|
+
end
|
159
|
+
|
160
|
+
enum :status, Status.to_attribute
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
164
|
+
> [!NOTE]
|
165
|
+
> `to_attribute` will transform keys using `String#underscore` if it is defined, otherwise it will use `Symbol#downcase`.
|
166
|
+
|
167
|
+
> [!TIP]
|
168
|
+
> You can also do custom transformations by passing a block to `to_attribute`. See the documentation for more details.
|
169
|
+
|
170
|
+
Using `to_attribute` allows you to use all of the Rails magic for enums, like scopes and boolean helpers, while also being able to refer to values in a safer way than hash lookups.
|
171
|
+
|
172
|
+
That is, these two are the same:
|
173
|
+
|
174
|
+
```ruby
|
175
|
+
Conversation.statuses[:active] # => 0
|
176
|
+
Conversation::Status::ACTIVE # => 0
|
177
|
+
```
|
178
|
+
|
179
|
+
But these are not:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
Conversation.statuses[:acitve]
|
183
|
+
# => nil
|
184
|
+
|
185
|
+
Conversation::Status::ACITVE # => nil
|
186
|
+
# =>
|
187
|
+
# uninitialized constant Conversation::Status::ACITVE (NameError)
|
188
|
+
# Did you mean? Conversation::Status::ACTIVE
|
189
|
+
```
|
190
|
+
|
191
|
+
You can get similar behavior using `#fetch`:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
Conversation.statuses.fetch(:acitve)
|
195
|
+
# => key not found: :acitve (KeyError)
|
196
|
+
# Did you mean? :active
|
197
|
+
```
|
198
|
+
|
199
|
+
But that still misses out on some of the DX benefits of using constants, like improved support for things like autocompletion, documentation, and navigation ("Go To Definition") in editors.
|
200
|
+
|
149
201
|
### `Nummy::MemberEnumerable`
|
150
202
|
|
151
203
|
`Nummy::MemberEnumerable` is a module that includes `Enumerable` and makes it possible to iterate over any class or module that responds to `members`.
|
data/lib/nummy/enum.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "json"
|
4
|
+
|
3
5
|
require "nummy/auto_sequenceable"
|
4
6
|
require "nummy/ordered_const_enumerable"
|
5
7
|
require "nummy/errors"
|
@@ -354,6 +356,79 @@ module Nummy
|
|
354
356
|
# Alias to support splatting enums into keyword args.
|
355
357
|
alias to_hash to_h
|
356
358
|
|
359
|
+
# Converts +self+ to a +Hash+ that can be converted to JSON.
|
360
|
+
#
|
361
|
+
# @return [Hash{String => Object}]
|
362
|
+
#
|
363
|
+
# @see .to_json
|
364
|
+
def as_json
|
365
|
+
to_h.transform_keys!(&:to_s)
|
366
|
+
end
|
367
|
+
|
368
|
+
# Converts +self+ to a +Hash+ and serializes it to a JSON string.
|
369
|
+
#
|
370
|
+
# Supports same options as +JSON#generate+.
|
371
|
+
#
|
372
|
+
# @return [String]
|
373
|
+
#
|
374
|
+
# @see .as_json
|
375
|
+
def to_json(*)
|
376
|
+
as_json.to_json(*)
|
377
|
+
end
|
378
|
+
|
379
|
+
# Converts the enum to a +Hash+ with snake_case keys.
|
380
|
+
#
|
381
|
+
# This is intended to be used with +ActiveRecord::Enum+, but can be used
|
382
|
+
# with any library that supports defining enums using a +Hash+ and expects
|
383
|
+
# to have lowercase keys.
|
384
|
+
#
|
385
|
+
# @overload to_attribute
|
386
|
+
# If +String#underscore+ is defined, converts the keys to snake_case
|
387
|
+
# by calling +underscore+ on the stringified key.
|
388
|
+
#
|
389
|
+
# Otherwise, converts each key using +Symbol#downcase+.
|
390
|
+
#
|
391
|
+
# @return [Hash{Symbol => Object}]
|
392
|
+
#
|
393
|
+
# @example Using with +ActiveRecord::Enum+.
|
394
|
+
# class Conversation < ActiveRecord::Base
|
395
|
+
# class Status < Nummy::Enum
|
396
|
+
# ACTIVE = auto
|
397
|
+
# ARCHIVED = auto
|
398
|
+
# end
|
399
|
+
#
|
400
|
+
# enum :status, Status.to_attribute
|
401
|
+
# end
|
402
|
+
#
|
403
|
+
# @overload to_attribute(&)
|
404
|
+
# Transforms the keys by calling the given block on each key.
|
405
|
+
#
|
406
|
+
# @yieldparam key [Symbol]
|
407
|
+
# @return [Hash{Symbol => Object}]
|
408
|
+
#
|
409
|
+
# @example Using custom key transformer.
|
410
|
+
# class ShippingStatus < Nummy::Enum
|
411
|
+
# IN_TRANSIT = auto
|
412
|
+
# OUT_FOR_DELIVERY = auto
|
413
|
+
# DELIVERED = auto
|
414
|
+
# end
|
415
|
+
#
|
416
|
+
# ShippingStatus.to_attribute { |key| key.to_s.underscore.camelize.to_sym }
|
417
|
+
# # => {:InTransit=>0, :OutForDelivery=>1, :Delivered=>2}
|
418
|
+
def to_attribute(&)
|
419
|
+
return to_h.transform_keys!(&) if block_given?
|
420
|
+
|
421
|
+
# Ignore coverage because it's executed in a forked process, which
|
422
|
+
# messes with the coverage collection.
|
423
|
+
# :nocov:
|
424
|
+
if String.method_defined?(:underscore)
|
425
|
+
return to_attribute { |key| key.to_s.underscore.to_sym }
|
426
|
+
end
|
427
|
+
# :nocov:
|
428
|
+
|
429
|
+
to_attribute(&:downcase)
|
430
|
+
end
|
431
|
+
|
357
432
|
# Returns a string representation of +self+.
|
358
433
|
#
|
359
434
|
# The string will contain the name-value pairs of the constants in +self+.
|
data/lib/nummy/version.rb
CHANGED