Skip to content

Commit

Permalink
Allow pattern matching solely against a result's data (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
benpickles authored May 12, 2024
1 parent dc43702 commit 8774b8a
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ end

## Pattern matching

An Operatic result also supports pattern matching in Ruby 2.7+ returning an array of `[success, data]`:
An Operatic result also supports pattern matching allowing you to match over a tuple of the result class and its data:

```ruby
case SayHello.call(name: 'Dave')
Expand All @@ -81,6 +81,17 @@ in [Operatic::Failure, _]
end
```

Or match solely against its data:

```ruby
case SayHello.call(name: 'Dave')
in message:
# Result has the `message` key, do something with the variable.
else
# Do something else.
end
```

Which might be consumed in Rails like this:

```ruby
Expand Down
23 changes: 23 additions & 0 deletions lib/operatic/result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,29 @@ def deconstruct
[self, to_h]
end

# Pattern match against the result's data via {#to_h}.
#
# @example
# class SayHello
# include Operatic
#
# def call
# data[:message] = 'Hello world'
# end
# end
#
# case SayHello.call
# in message:
# # Result has the `message` key, do something with the variable.
# else
# # Do something else.
# end
#
# @return [Hash<Symbol, anything>]
def deconstruct_keys(keys = nil)
to_h
end

# @return [self]
def freeze
data.freeze
Expand Down
15 changes: 15 additions & 0 deletions spec/lib/operatic/result_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@
end
end

describe '#deconstruct_keys (pattern matching)' do
subject { described_class.new(data) }

let(:data) { Operatic::Data.new(a: 1, b: 2, c: 3) }

it 'matches against its data' do
deconstructed = case subject
in a:, c:
[a, c]
end

expect(deconstructed).to eql([1, 3])
end
end

describe '#method_missing / #respond_to?' do
subject { described_class.new(data) }

Expand Down

0 comments on commit 8774b8a

Please sign in to comment.