philiprehberger-enum 0.2.0 → 0.4.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 +15 -0
- data/README.md +46 -0
- data/lib/philiprehberger/enum/version.rb +1 -1
- data/lib/philiprehberger/enum.rb +68 -0
- 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: 2b55ad3be49fe204aa1e0588dca8f25995f0589f49c3c0aa6c77e670e03fa7b0
|
|
4
|
+
data.tar.gz: dd879b2ed6f61c12c3805b6b6a86cc4aac4391e383251a3188a60925989685ab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c29b4d8bb1a41e1a045363596d673febbaf7c6c984d99754ca1caafbbc7535ffdf92cbd3693464af201924f1d1cd2961b135f7c3fd97c4d66f5f34875f93e389
|
|
7
|
+
data.tar.gz: 50e33959a328aa0781d2a863df411e76b580ce6788a7b5bbf667078c74dfcb539eaa1b82c92612b2e34e7086dcb32e33de589a43edcc0b6107520c7c72e38e21
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-04-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `Enum.slice(*names)` returns an array of members matching the given symbol names, silently skipping unknown names
|
|
14
|
+
- `Enum.sample(n = nil)` returns a random member when called without argument, or an array of n random members when called with an integer
|
|
15
|
+
|
|
16
|
+
## [0.3.0] - 2026-04-09
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
- `Enum.fetch(name)` strict lookup that raises `Error` if the name is not a member (case-insensitive fallback)
|
|
20
|
+
- `Enum.fetch_by_value(val)` strict value lookup that raises `Error` if no member has the given value
|
|
21
|
+
- `Enum.names` returns a frozen array of all member name symbols in declaration order
|
|
22
|
+
- `Enum.values` returns a frozen array of all member values in declaration order
|
|
23
|
+
- `Enum.first` / `Enum.last` return the first and last declared members
|
|
24
|
+
|
|
10
25
|
## [0.2.0] - 2026-04-03
|
|
11
26
|
|
|
12
27
|
### Added
|
data/README.md
CHANGED
|
@@ -84,6 +84,45 @@ Status.size # => 3
|
|
|
84
84
|
Status.count # => 3
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
### Strict Lookup
|
|
88
|
+
|
|
89
|
+
`fetch` and `fetch_by_value` raise an error instead of returning `nil`:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
Status.fetch(:draft) # => Status::DRAFT
|
|
93
|
+
Status.fetch(:unknown) # raises Philiprehberger::Enum::Error
|
|
94
|
+
HttpCode.fetch_by_value(200) # => HttpCode::OK
|
|
95
|
+
HttpCode.fetch_by_value(999) # raises Philiprehberger::Enum::Error
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Names, Values, First & Last
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
HttpCode.names # => [:ok, :not_found, :server_error]
|
|
102
|
+
HttpCode.values # => [200, 404, 500]
|
|
103
|
+
Status.first # => Status::DRAFT
|
|
104
|
+
Status.last # => Status::ARCHIVED
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Slice
|
|
108
|
+
|
|
109
|
+
`slice` returns members matching the given names, silently skipping any that are unknown:
|
|
110
|
+
|
|
111
|
+
```ruby
|
|
112
|
+
Status.slice(:draft, :archived) # => [Status::DRAFT, Status::ARCHIVED]
|
|
113
|
+
Status.slice(:draft, :nonexistent) # => [Status::DRAFT]
|
|
114
|
+
Status.slice(:archived, :draft) # => [Status::ARCHIVED, Status::DRAFT]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Sample
|
|
118
|
+
|
|
119
|
+
`sample` returns a random member. Pass an integer to get an array:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
Status.sample # => Status::DRAFT (random)
|
|
123
|
+
Status.sample(2) # => [Status::PUBLISHED, Status::ARCHIVED] (random)
|
|
124
|
+
```
|
|
125
|
+
|
|
87
126
|
### Case-Insensitive Lookup
|
|
88
127
|
|
|
89
128
|
`from_name` tries an exact match first, then falls back to case-insensitive:
|
|
@@ -133,9 +172,16 @@ Status::DRAFT.to_json # => '{"name":"draft","ordinal":0,"value":null}'
|
|
|
133
172
|
| `.to_h` | Return `{ name_symbol => value }` hash |
|
|
134
173
|
| `.members_by_value` | Return `{ value => member }` reverse lookup hash |
|
|
135
174
|
| `.size` / `.count` | Return the number of defined members |
|
|
175
|
+
| `.names` | Return a frozen array of member name symbols |
|
|
176
|
+
| `.values` | Return a frozen array of member values |
|
|
177
|
+
| `.first` / `.last` | Return the first or last declared member |
|
|
178
|
+
| `.fetch(name)` | Strict lookup by name; raises `Error` if not found |
|
|
179
|
+
| `.fetch_by_value(val)` | Strict lookup by value; raises `Error` if not found |
|
|
136
180
|
| `.from_name(name)` | Look up by name (case-insensitive fallback) |
|
|
137
181
|
| `.from_string(string)` | Look up a member by string name |
|
|
138
182
|
| `.from_value(val)` | Look up a member by custom value |
|
|
183
|
+
| `.slice(*names)` | Return members matching the given symbol names, skipping unknowns |
|
|
184
|
+
| `.sample(n = nil)` | Return a random member, or array of n random members |
|
|
139
185
|
| `.valid?(name)` | Check if a name is a valid member |
|
|
140
186
|
| `#name` | Return the member name as a symbol |
|
|
141
187
|
| `#ordinal` | Return the ordinal position |
|
data/lib/philiprehberger/enum.rb
CHANGED
|
@@ -168,6 +168,56 @@ module Philiprehberger
|
|
|
168
168
|
member_registry.values.find { |m| m.value == val }
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
+
# Look up a member by name, raising if not found
|
|
172
|
+
#
|
|
173
|
+
# @param name [Symbol, String] the member name
|
|
174
|
+
# @return [Enum] the member
|
|
175
|
+
# @raise [Error] if the name is not a valid member
|
|
176
|
+
def fetch(name)
|
|
177
|
+
from_name(name) || raise(Error, "no member #{name.inspect} on #{self}")
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Look up a member by value, raising if not found
|
|
181
|
+
#
|
|
182
|
+
# @param val [Object] the value to search for
|
|
183
|
+
# @return [Enum] the member
|
|
184
|
+
# @raise [Error] if the value is not found
|
|
185
|
+
def fetch_by_value(val)
|
|
186
|
+
from_value(val) || raise(Error, "no member with value #{val.inspect} on #{self}")
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Return all member names in declaration order
|
|
190
|
+
#
|
|
191
|
+
# @return [Array<Symbol>] frozen array of member names
|
|
192
|
+
def names
|
|
193
|
+
freeze_members!
|
|
194
|
+
member_registry.keys.freeze
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Return all member values in declaration order
|
|
198
|
+
#
|
|
199
|
+
# @return [Array<Object>] frozen array of member values
|
|
200
|
+
def values
|
|
201
|
+
freeze_members!
|
|
202
|
+
member_registry.values.map(&:value).freeze
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Return the first declared member
|
|
206
|
+
#
|
|
207
|
+
# @return [Enum, nil] the first member, or nil if empty
|
|
208
|
+
def first
|
|
209
|
+
freeze_members!
|
|
210
|
+
member_registry.values.first
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Return the last declared member
|
|
214
|
+
#
|
|
215
|
+
# @return [Enum, nil] the last member, or nil if empty
|
|
216
|
+
def last
|
|
217
|
+
freeze_members!
|
|
218
|
+
member_registry.values.last
|
|
219
|
+
end
|
|
220
|
+
|
|
171
221
|
# Check if a name is a valid member
|
|
172
222
|
#
|
|
173
223
|
# @param name [Symbol, String] the member name
|
|
@@ -177,6 +227,24 @@ module Philiprehberger
|
|
|
177
227
|
member_registry.key?(name.to_sym)
|
|
178
228
|
end
|
|
179
229
|
|
|
230
|
+
# Return members matching the given symbol names, silently skipping unknown names
|
|
231
|
+
#
|
|
232
|
+
# @param names [Array<Symbol>] the member names to look up
|
|
233
|
+
# @return [Array<Enum>] array of matching members in the given order
|
|
234
|
+
def slice(*names)
|
|
235
|
+
freeze_members!
|
|
236
|
+
names.filter_map { |n| member_registry[n.to_sym] }
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# Return a random member or array of random members
|
|
240
|
+
#
|
|
241
|
+
# @param n [Integer, nil] number of members to return; nil returns a single member
|
|
242
|
+
# @return [Enum, Array<Enum>] single member if n is nil, array of n members otherwise
|
|
243
|
+
def sample(n = nil)
|
|
244
|
+
freeze_members!
|
|
245
|
+
n.nil? ? member_registry.values.sample : member_registry.values.sample(n)
|
|
246
|
+
end
|
|
247
|
+
|
|
180
248
|
private
|
|
181
249
|
|
|
182
250
|
def inherited(subclass)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-enum
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Define type-safe enums in Ruby with automatic ordinals, custom values,
|
|
14
14
|
lookup methods, and Ruby 3.x pattern matching support. A cleaner alternative to
|