Skip to content

Commit 0066cf0

Browse files
committed
feat: include Comparable module, add test for it
1 parent 9b11429 commit 0066cf0

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

spec/option_spec.cr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,15 @@ describe Option do
224224
Option.from!(env_user).should eq(Some[%x(whoami).chomp])
225225
Option.from!(env_not_existing).should eq(None(String)[])
226226
end
227+
228+
it "<=>" do
229+
a = None(Int32)[]
230+
b = Some[0]
231+
c = Some[1]
232+
233+
(a < b).should be_true
234+
(b < c).should be_true
235+
236+
expect_raises(Option::Uncomparable) { a <=> 0 }
237+
end
227238
end

spec/result_spec.cr

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,23 @@ describe Result do
233233
Result.from_or!(false, env_user).should eq(Ok(String, Bool)[%x(whoami).chomp])
234234
Result.from_or!(false, env_not_existing).should eq(Err(String, Bool)[false])
235235
end
236+
237+
it "<=>" do
238+
x1 = Ok(Int32, String)[1]
239+
y1 = Err(Int32, String)["error"]
240+
241+
(x1 < y1).should be_true
242+
243+
x2 = Ok(Int32, String)[0]
244+
y2 = Ok(Int32, String)[1]
245+
246+
(x2 < y2).should be_true
247+
248+
x3 = Err(Int32, Int32)[0]
249+
y3 = Err(Int32, Int32)[1]
250+
251+
(x3 < y3).should be_true
252+
253+
expect_raises(Result::Uncomparable) { x1 <=> 0 }
254+
end
236255
end

src/option.cr

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ require "./result"
33
abstract struct Option(T)
44
class UnwrapNone < Exception; end
55

6+
class Uncomparable < Exception; end
7+
68
macro inherited
79
{% type = @type.name(generic_args: false).stringify %}
810

@@ -285,6 +287,23 @@ abstract struct Option(T)
285287
rescue
286288
None(T).new
287289
end
290+
291+
include Comparable(self)
292+
293+
def <=>(other) : Int32
294+
case {self, other}
295+
when {Some, Some}
296+
self.unwrap <=> other.unwrap
297+
when {Some, None}
298+
1
299+
when {None, Some}
300+
-1
301+
when {None, None}
302+
0
303+
else
304+
raise Uncomparable.new("Cannot compare Option with #{other.class}")
305+
end
306+
end
288307
end
289308

290309
struct Some(T) < Option(T)

src/result.cr

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ abstract struct Result(T, E)
33

44
class UnwrapErrOnOk < Exception; end
55

6+
class Uncomparable < Exception; end
7+
68
macro inherited
79
{% type = @type.name(generic_args: false).stringify %}
810

@@ -290,6 +292,23 @@ abstract struct Result(T, E)
290292
rescue
291293
Err(T, E).new(error)
292294
end
295+
296+
include Comparable(self)
297+
298+
def <=>(other) : Int32
299+
case {self, other}
300+
when {Ok, Ok}
301+
self.unwrap <=> other.unwrap
302+
when {Ok, Err}
303+
-1
304+
when {Err, Ok}
305+
1
306+
when {Err, Err}
307+
self.unwrap_err <=> other.unwrap_err
308+
else
309+
raise Uncomparable.new("Cannot compare Result with #{other.class}")
310+
end
311+
end
293312
end
294313

295314
struct Ok(T, E) < Result(T, E)

0 commit comments

Comments
 (0)