philiprehberger-struct_kit 0.4.0 → 0.6.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 +18 -3
- data/README.md +29 -0
- data/lib/philiprehberger/struct_kit/definition.rb +17 -1
- data/lib/philiprehberger/struct_kit/version.rb +1 -1
- 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: 68b7bec33faa5c7e50b69e236a0787c370b8303e8024ea4d2a26f6751e3e5850
|
|
4
|
+
data.tar.gz: c04c4c2eea2bbc45a7d12cf8e6b3560b1f75699917c105378e3b67f4c5a44e42
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: baafc26c5ed314e8968fffe950acfdec20de931582a47002ccb26bcba7906caf11add73365f3a637b15fa128be1e4467cbee907b7194fe926d3927a076e1a751
|
|
7
|
+
data.tar.gz: 56cda98ec744f87b058f66f0afa69d3ac7d087a0ba7350662707c12495758b2e4992210cd581fd01f6d79faaa3d2e08063f13e8a6d1377f11a501e8fd8336d03
|
data/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this gem will be documented in this file.
|
|
4
4
|
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.
|
|
6
|
-
and this
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-05-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Generated structs gain `#match?(**pattern)` — returns `true` when every key in the pattern matches the struct's value via `===` (case equality). Pairs with `deconstruct_keys` for partial-attribute checks.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- CHANGELOG header normalised to reference Keep a Changelog v1.0.0 and "this project adheres" to match every other Ruby gem.
|
|
17
|
+
|
|
18
|
+
## [0.5.0] - 2026-04-18
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- `.from_a(array)` class method on generated structs — constructs an instance from field values in declaration order; inverse of `#to_a`; raises `ArgumentError` on length mismatch
|
|
22
|
+
|
|
10
23
|
## [0.4.0] - 2026-04-16
|
|
11
24
|
|
|
12
25
|
### Added
|
|
@@ -117,7 +130,9 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
117
130
|
- Value equality via `#==`
|
|
118
131
|
- Keyword-only constructor
|
|
119
132
|
|
|
120
|
-
[Unreleased]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.
|
|
133
|
+
[Unreleased]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.6.0...HEAD
|
|
134
|
+
[0.6.0]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.5.0...v0.6.0
|
|
135
|
+
[0.5.0]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.4.0...v0.5.0
|
|
121
136
|
[0.4.0]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.3.1...v0.4.0
|
|
122
137
|
[0.3.1]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.3.0...v0.3.1
|
|
123
138
|
[0.3.0]: https://github.com/philiprehberger/rb-struct-kit/compare/v0.2.0...v0.3.0
|
data/README.md
CHANGED
|
@@ -124,6 +124,15 @@ in { role: :user }
|
|
|
124
124
|
end
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
### Pattern-Style Match
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
user = User.new(name: 'Alice', age: 30, role: :user)
|
|
131
|
+
user.match?(role: :user) # => true
|
|
132
|
+
user.match?(age: 18..30) # => true (uses === for case equality)
|
|
133
|
+
user.match?(name: /^A/) # => true
|
|
134
|
+
```
|
|
135
|
+
|
|
127
136
|
### Non-destructive Updates
|
|
128
137
|
|
|
129
138
|
```ruby
|
|
@@ -177,6 +186,24 @@ Account.new(email: '', tags: ['a']) # ArgumentError: email must be present
|
|
|
177
186
|
Account.new(email: 'a@b', tags: []) # ArgumentError: tags must be present
|
|
178
187
|
```
|
|
179
188
|
|
|
189
|
+
### Positional constructor
|
|
190
|
+
|
|
191
|
+
```ruby
|
|
192
|
+
require 'philiprehberger/struct_kit'
|
|
193
|
+
|
|
194
|
+
Point = Philiprehberger::StructKit.define do
|
|
195
|
+
field :x, Integer
|
|
196
|
+
field :y, Integer
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
p = Point.from_a([1, 2])
|
|
200
|
+
p.x # => 1
|
|
201
|
+
p.y # => 2
|
|
202
|
+
|
|
203
|
+
# Roundtrip with #to_a
|
|
204
|
+
Point.from_a(p.to_a) == p # => true
|
|
205
|
+
```
|
|
206
|
+
|
|
180
207
|
### Introspection
|
|
181
208
|
|
|
182
209
|
```ruby
|
|
@@ -212,6 +239,7 @@ Define a new struct class. Evaluates the block in DSL context.
|
|
|
212
239
|
| `#with(**changes)` | Return a new instance with the given fields changed |
|
|
213
240
|
| `#with(**overrides)` | Immutable copy-with: return a new instance with selected fields replaced (re-validated) |
|
|
214
241
|
| `#deconstruct_keys(keys)` | Pattern matching support |
|
|
242
|
+
| `#match?(**pattern)` | Returns true when every key in pattern matches via `===` |
|
|
215
243
|
| `#==` | Value equality |
|
|
216
244
|
| `#inspect` | Human-readable string representation |
|
|
217
245
|
|
|
@@ -220,6 +248,7 @@ Define a new struct class. Evaluates the block in DSL context.
|
|
|
220
248
|
| Method | Description |
|
|
221
249
|
|--------|-------------|
|
|
222
250
|
| `.from_h(hash)` | Construct from hash (string or symbol keys) |
|
|
251
|
+
| `.from_a(array)` | Construct from an array of values in field-declaration order (inverse of `#to_a`) |
|
|
223
252
|
| `.field_names` | Return the declared field names in order |
|
|
224
253
|
|
|
225
254
|
## Development
|
|
@@ -25,7 +25,7 @@ module Philiprehberger
|
|
|
25
25
|
@validations[field_name] << block if block
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def build # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
28
|
+
def build # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
29
29
|
fields = @fields.dup
|
|
30
30
|
mutable = @mutable
|
|
31
31
|
|
|
@@ -105,6 +105,15 @@ module Philiprehberger
|
|
|
105
105
|
new(**sym_hash)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
+
define_singleton_method(:from_a) do |array|
|
|
109
|
+
if array.length != _fields.size
|
|
110
|
+
raise ArgumentError,
|
|
111
|
+
"expected #{_fields.size} values for #{_fields.keys}, got #{array.length}"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
new(**_fields.keys.zip(array).to_h)
|
|
115
|
+
end
|
|
116
|
+
|
|
108
117
|
define_singleton_method(:field_names) do
|
|
109
118
|
_fields.keys
|
|
110
119
|
end
|
|
@@ -114,6 +123,13 @@ module Philiprehberger
|
|
|
114
123
|
keys ? h.slice(*keys) : h
|
|
115
124
|
end
|
|
116
125
|
|
|
126
|
+
define_method(:match?) do |**pattern|
|
|
127
|
+
unknown = pattern.keys - self.class._fields.keys
|
|
128
|
+
raise ArgumentError, "unknown keyword: #{unknown.first}" unless unknown.empty?
|
|
129
|
+
|
|
130
|
+
pattern.all? { |k, v| v === instance_variable_get(:"@#{k}") } # rubocop:disable Style/CaseEquality
|
|
131
|
+
end
|
|
132
|
+
|
|
117
133
|
define_method(:==) do |other|
|
|
118
134
|
other.is_a?(self.class) && to_h == other.to_h
|
|
119
135
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-struct_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.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-
|
|
11
|
+
date: 2026-05-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Define data classes with typed fields, default values, validation rules,
|
|
14
14
|
and pattern matching support. Immutable by default with keyword-only construction,
|