Skip to content

Commit

Permalink
Literal::Array#narrow type narrowing (#233)
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldrapper authored Nov 28, 2024
1 parent d72479b commit dd94d81
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lib/literal/array.rb
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,23 @@ def minmax(...)
__with__(@__value__.minmax(...))
end

def narrow(type)
return self if __type__ == type

unless Literal.subtype?(type, of: @__type__)
raise ArgumentError.new("Cannot narrow #{@__type__} to #{type}")
end

@__value__.each do |item|
Literal.check(actual: item, expected: type) do |c|
c.fill_receiver(receiver: self, method: "#narrow")
end
end

@__type__ = type
self
end

def one?(...)
@__value__.one?(...)
end
Expand Down
30 changes: 30 additions & 0 deletions test/array.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,33 @@
expect(Literal::Array(Integer).new(1, 2, 3).sum) == 6
expect(Literal::Array(String).new("1", "2", "3").sum(&:to_i)) == 6
end

test "#narrow" do
array = Literal::Array(Numeric).new(1, 2, 3)

refute Literal::Array(Integer) === array
array.narrow(Integer)
assert Literal::Array(Integer) === array
end

test "#narrow with same type" do
array = Literal::Array(Numeric).new(1, 2, 3)

assert Literal::Array(Numeric) === array
end

test "#narrow with wrong value" do
array = Literal::Array(Numeric).new(1, 2, 3.456)

expect {
array.narrow(Integer)
}.to_raise(Literal::TypeError)
end

test "#narrow with wrong type" do
array = Literal::Array(Integer).new(1, 2, 3)

expect {
array.narrow(Numeric)
}.to_raise(ArgumentError)
end

0 comments on commit dd94d81

Please sign in to comment.