Skip to content

Commit 7fb0d3f

Browse files
committed
feat: add pattern matching by deconstruct
1 parent c3a6317 commit 7fb0d3f

5 files changed

Lines changed: 74 additions & 7 deletions

File tree

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,6 @@ Layout/LineLength:
3939

4040
Lint/UnusedBlockArgument:
4141
Enabled: false
42+
43+
Style/ConditionalAssignment:
44+
EnforcedStyle: assign_to_condition

lib/rs/option.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ def ==(other)
183183
other.is_a?(Some) && @value == other.unwrap && @value_type == other.value_type
184184
end
185185

186+
def deconstruct
187+
[self, @value]
188+
end
189+
186190
def initialize(value)
187191
if value == nil
188192
raise WrapNil.new("Cannot create Some[T](value) with nil")
@@ -208,6 +212,10 @@ def ==(other)
208212
other.is_a?(None) && @value_type == other.value_type
209213
end
210214

215+
def deconstruct
216+
[self]
217+
end
218+
211219
def initialize(value_type = Class)
212220
if !value_type.is_a?(Class)
213221
raise TypeError.new(value_type)

lib/rs/result.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ def ==(other)
204204
other.is_a?(Ok) && @value == other.unwrap && @value_type == other.value_type && @error_type == other.error_type
205205
end
206206

207+
def deconstruct
208+
[self, @value]
209+
end
210+
207211
def initialize(value)
208212
if value == nil
209213
raise WrapNil.new("Cannot create Ok[T, E] with nil")
@@ -250,6 +254,10 @@ def ==(other)
250254
other.is_a?(Err) && @error == other.unwrap_err && @value_type == other.value_type && @error_type == other.error_type
251255
end
252256

257+
def deconstruct
258+
[self, @error]
259+
end
260+
253261
def initialize(error)
254262
if error == nil
255263
raise WrapNil.new("Cannot create Err[T, E] with nil")

spec/rs/option_spec.rb

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
expect(y.unwrap_or(0)).to eq 12
107107
end
108108

109-
it "pattern_matching" do
109+
it "pattern matching" do
110110
def divide(numerator, denominator)
111111
if denominator == 0
112112
None[Float]
@@ -116,13 +116,35 @@ def divide(numerator, denominator)
116116
end
117117

118118
result = divide(3.0, 1.0)
119-
case result
120-
when Some
121-
x = result.unwrap
122-
else
123-
x = "Cannot divide by 0"
124-
end
119+
x = case result
120+
when Some
121+
result.unwrap
122+
else
123+
"Cannot divide by 0"
124+
end
125125
expect(x).to eq 3.0
126+
127+
x = Some.new(2)
128+
tx = case x
129+
in Some, Integer => i
130+
i
131+
in Some, Float => f
132+
f
133+
in None
134+
0
135+
end
136+
137+
expect(tx).to eq 2
138+
139+
x = None.new
140+
tx = case x
141+
in Some, any
142+
any
143+
in None
144+
0
145+
end
146+
147+
expect(tx).to eq 0
126148
end
127149

128150
it "type ==" do

spec/rs/result_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,32 @@
1919
expect { Err.new(nil) }.to raise_error Rs::Result::WrapNil
2020
end
2121

22+
it "pattern matching" do
23+
x = Ok[Float, String] { 2.0 }
24+
tx = case x
25+
in Ok, Integer => i
26+
i
27+
in Ok, Float => f
28+
f
29+
in Err, String => str
30+
str
31+
else
32+
"mismatch"
33+
end
34+
35+
expect(tx).to eq 2.0
36+
37+
x = Err[Float, String] { "foo" }
38+
tx = case x
39+
in Ok, any
40+
any
41+
in Err, str
42+
str
43+
end
44+
45+
expect(tx).to eq "foo"
46+
end
47+
2248
it "is_ok" do
2349
x = Ok.new(-3)
2450
expect(x.is_ok).to be true

0 commit comments

Comments
 (0)