Skip to content

Commit

Permalink
Fix key type for empty NamedTuple be Symbol (#10942)
Browse files Browse the repository at this point in the history
  • Loading branch information
caspiano authored Jul 27, 2021
1 parent 3cc36c9 commit 362c730
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 15 deletions.
36 changes: 27 additions & 9 deletions spec/std/named_tuple_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ describe "NamedTuple" do
typeof(val).should eq(Int32 | Char | Nil)
end

describe "dig?" do
describe "#dig?" do
it "gets the value at given path given splat" do
h = {a: {b: {c: [10, 20]}}, x: {a: "b"}}

Expand All @@ -165,7 +165,7 @@ describe "NamedTuple" do
end
end

describe "dig" do
describe "#dig" do
it "gets the value at given path given splat" do
h = {a: {b: {c: [10, 20]}}, x: {a: "b", c: nil}}

Expand Down Expand Up @@ -290,9 +290,18 @@ describe "NamedTuple" do
NamedTuple.new.empty?.should be_true
end

it "does to_a" do
tup = {a: 1, b: 'a'}
tup.to_a.should eq([{:a, 1}, {:b, 'a'}])
describe "#to_a" do
it "creates an array of key-value pairs" do
tup = {a: 1, b: 'a'}
tup.to_a.should eq([{:a, 1}, {:b, 'a'}])
end

it "preserves key type for empty named tuples" do
tup = NamedTuple.new
arr = tup.to_a
arr.should be_empty
arr.should be_a(Array({Symbol, NoReturn}))
end
end

it "does map" do
Expand Down Expand Up @@ -327,10 +336,19 @@ describe "NamedTuple" do
u.should_not eq(v)
end

it "does to_h" do
tup1 = {a: 1, b: "hello"}
hash = tup1.to_h
hash.should eq({:a => 1, :b => "hello"})
describe "#to_h" do
it "creates a hash" do
tup1 = {a: 1, b: "hello"}
hash = tup1.to_h
hash.should eq({:a => 1, :b => "hello"})
end

it "creates an empty hash from an empty named tuple" do
tup = NamedTuple.new
hash = tup.to_h
hash.should be_empty
hash.should be_a(Hash(Symbol, NoReturn))
end
end

it "does to_s" do
Expand Down
20 changes: 14 additions & 6 deletions src/named_tuple.cr
Original file line number Diff line number Diff line change
Expand Up @@ -498,12 +498,18 @@ struct NamedTuple
# tuple = {name: "Crystal", year: 2011}
# tuple.to_a # => [{:name, "Crystal"}, {:year, 2011}]
# ```
#
# NOTE: `to_a` on an empty named tuple produces an `Array(Tuple(Symbol, NoReturn))`
def to_a
ary = Array({typeof(first_key_internal), typeof(first_value_internal)}).new(size)
each do |key, value|
ary << {key.as(typeof(first_key_internal)), value.as(typeof(first_value_internal))}
end
ary
{% if T.size == 0 %}
[] of {Symbol, NoReturn}
{% else %}
[
{% for key in T %}
{ {{key.symbolize}}, self[{{key.symbolize}}] },
{% end %}
]
{% end %}
end

# Returns a `Hash` with the keys and values in this named tuple.
Expand All @@ -512,9 +518,11 @@ struct NamedTuple
# tuple = {name: "Crystal", year: 2011}
# tuple.to_h # => {:name => "Crystal", :year => 2011}
# ```
#
# NOTE: `to_h` on an empty named tuple produces a `Hash(Symbol, NoReturn)`
def to_h
{% if T.size == 0 %}
{} of NoReturn => NoReturn
{} of Symbol => NoReturn
{% else %}
{
{% for key in T %}
Expand Down

0 comments on commit 362c730

Please sign in to comment.