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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 870e3019e2981514154a2d9e9ea3c21398fbd009fe99e9511ecebcfc5162e6ef
4
- data.tar.gz: fd6725e19f0dc48131ec4ee3143cf97c5db29b63bf30dbea8ed0edbc26fa1d15
3
+ metadata.gz: 2b55ad3be49fe204aa1e0588dca8f25995f0589f49c3c0aa6c77e670e03fa7b0
4
+ data.tar.gz: dd879b2ed6f61c12c3805b6b6a86cc4aac4391e383251a3188a60925989685ab
5
5
  SHA512:
6
- metadata.gz: 4ac450c34e480d9036875c23c0e91f691d8b08695c7fab01f326ca5d5af53663d125786ffc05503bd37c4b98122cdb1d25e1c4305cf2d3507323df3692cd2b47
7
- data.tar.gz: c63863fc33b8c4d25fd09c038ad25c9e782649077bae2bb4d9fca096453ab68d84f621c807f46af57fbba8225115a0c60e3a8fde7ccbcb6946ec9831c6d34ca9
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 |
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  class Enum
5
- VERSION = '0.2.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -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.2.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-04 00:00:00.000000000 Z
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