Skip to content

Commit

Permalink
Support Ruby 2.7+ Pattern Matching
Browse files Browse the repository at this point in the history
Add `#deconstruct_keys` to `Expression::Base` and `Schedule` so that
they can be used in pattern matches.

In our products, we've been using `#to_h` for this, and it would be
nice sugar to have it built in.

A common example we've used in our products is building a
humanized-readable version of a schedule. An extremely stripped down
version might look something like this

```ruby
case existing_user_schedule
in weekday: { weekday: }
  "Every #{weekday}"
in day_in_month: { day: }
  "Last #{day} of every month"
end
```
  • Loading branch information
danielma committed Apr 18, 2024
1 parent c53085d commit fb1d64e
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

### Unreleased

Changes:

* Support pattern matching for `Expression` and `Schedule`

[Commits](https://github.com/molawson/repeatable/compare/v1.1.0...main)

### 1.1.0 (2022-02-25)
Expand Down
5 changes: 5 additions & 0 deletions lib/repeatable/expression/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def to_h
{hash_key => hash_value}
end

sig { params(_keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.any(Types::SymbolHash, T::Array[Types::SymbolHash])]) }
def deconstruct_keys(_keys)
to_h
end

sig { params(other: Expression::Base).returns(Expression::Union) }
def union(other)
Union.new(self, other)
Expand Down
5 changes: 5 additions & 0 deletions lib/repeatable/schedule.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ def to_h
expression.to_h
end

sig { params(_keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.any(Types::SymbolHash, T::Array[Types::SymbolHash])]) }
def deconstruct_keys(_keys)
to_h
end

sig { params(other: Object).returns(T::Boolean) }
def ==(other)
other.is_a?(self.class) && expression == other.expression
Expand Down
8 changes: 8 additions & 0 deletions spec/repeatable/schedule_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,14 @@ module Repeatable
end
end

describe "pattern matching" do
let(:arg) { nested_set_expression_hash }

it "can #deconstruct_keys" do
expect(subject.deconstruct_keys(nil)).to eq subject.to_h
end
end

describe "#==" do
it "returns true if the schedules have the same identity" do
schedule = described_class.new(nested_set_expression_object)
Expand Down
6 changes: 6 additions & 0 deletions spec/support/expression_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@
expect { subject.to_h }.not_to raise_error
end
end

describe "pattern matching" do
it "can #deconstruct_keys" do
expect(subject.deconstruct_keys(nil)).to be_a(Hash)
end
end
end

0 comments on commit fb1d64e

Please sign in to comment.