Skip to content

Commit 19d8b52

Browse files
committed
feat: add from from? from! methods to Option
So we can conv the std lib to Option type to get a no nil world
1 parent 485df4d commit 19d8b52

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

spec/option_spec.cr

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,26 @@ describe Option do
216216
expect_raises(Option::WrapingNil) { Some(Bool?)[false] }
217217
expect_raises(Option::WrapingNil) { None(Bool?)[] }
218218
end
219+
220+
it "from" do
221+
Option.from(0).should eq(Some[0])
222+
Option.from("").should eq(Some[""])
223+
Option.from(false).should eq(Some[false])
224+
Option.from([] of Int32).should eq(Some[[] of Int32])
225+
Option.from({} of String => Int32).should eq(Some[{} of String => Int32])
226+
227+
Option(Bool).from?(nil).should eq(None(Bool)[])
228+
expect_raises(Option::WrapingNil) { Option.from?(nil) }
229+
230+
Option(String).from?(ENV["USER"]?).should eq(Some[%x(whoami).chomp])
231+
Option(String).from?(ENV["NOT_EXISTING"]?).should eq(None(String)[])
232+
233+
Option.from! { ENV["USER"] }.should eq(Some[%x(whoami).chomp])
234+
Option.from! { ENV["NOT_EXISTING"] }.should eq(None(String)[])
235+
236+
env_user = -> { ENV["USER"] }
237+
env_not_existing = -> { ENV["NOT_EXISTING"] }
238+
Option.from!(env_user).should eq(Some[%x(whoami).chomp])
239+
Option.from!(env_not_existing).should eq(None(String)[])
240+
end
219241
end

src/option.cr

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ abstract struct Option(T)
9898

9999
def map(&block : T -> U) : Option(U) forall U
100100
{% if type == "Some" %}
101-
Some.new(block.call(@value))
101+
Some(U).new(block.call(@value))
102102
{% elsif type == "None" %}
103103
None(U).new
104104
{% end %}
105105
end
106106

107107
def map(block : T -> U) : Option(U) forall U
108108
{% if type == "Some" %}
109-
Some.new(block.call(@value))
109+
Some(U).new(block.call(@value))
110110
{% elsif type == "None" %}
111111
None(U).new
112112
{% end %}
@@ -267,6 +267,26 @@ abstract struct Option(T)
267267
end
268268
end
269269
end
270+
271+
def self.from(value : T) : Option(T)
272+
Some(T).new(value)
273+
end
274+
275+
def self.from?(value : T | Nil) : Option(T)
276+
value.nil? ? None(T).new : Some(T).new(value)
277+
end
278+
279+
def self.from!(&block : -> T) : Option(T)
280+
Some(T).new(block.call)
281+
rescue
282+
None(T).new
283+
end
284+
285+
def self.from!(block : -> T) : Option(T)
286+
Some(T).new(block.call)
287+
rescue
288+
None(T).new
289+
end
270290
end
271291

272292
struct Some(T) < Option(T)

0 commit comments

Comments
 (0)