require 'facets/core/hash/normalize_keys'

class Hash

  # Converts all keys in the Hash to Strings, returning a new Hash.
  # With a +filter+ parameter, limits conversion to only a certain selection of keys.
  #
  #   foo = { :name=>'Gavin', :wife=>:Lisa }
  #   foo.stringify_keys    #=>  { "name"=>"Gavin", "wife"=>:Lisa }
  #   foo.inspect           #=>  { :name =>"Gavin", :wife=>:Lisa }
  #
  #--
  # Adapted from Gavin Sinclair's #convert_keys.
  #++
  def stringify_keys( &filter )
    if filter
      normalize_keys{ |k| filter[k] ? k.to_s : nil }
    else
      normalize_keys{ |k| k.to_s }
    end
  end

  alias_method(:keys_to_s, :stringify_keys)

  # Synonym for Hash#stringify_keys, but modifies the receiver in place and returns it.
  # With a +filter+ parameter, limits conversion to only a certain selection of keys.
  #
  #   foo = { :name=>'Gavin', :wife=>:Lisa }
  #   foo.stringify_keys!    #=>  { "name"=>"Gavin", "wife"=>:Lisa }
  #   foo.inspect            #=>  { "name"=>"Gavin", "wife"=>:Lisa }
  #
  #--
  # Adapted from Gavin Sinclair's #convert_keys.
  #++
  def stringify_keys!( &filter )
    if filter
      normalize_keys!{ |k| filter[k] ? k.to_s : nil }
    else
      normalize_keys!{ |k| k.to_s }
    end
  end

  alias_method( :keys_to_s!, :stringify_keys!)

end


#  _____         _
# |_   _|__  ___| |_
#   | |/ _ \/ __| __|
#   | |  __/\__ \ |_
#   |_|\___||___/\__|
#
=begin test

  require 'test/unit'

  class TCHash < Test::Unit::TestCase

    def test_keys_to_s
      foo = { :a=>1, :b=>2 }
      assert_equal( { "a"=>1, "b"=>2 }, foo.stringify_keys )
      assert_equal( { :a =>1, :b=>2 }, foo  )
    end

    def test_keys_to_s!
      foo = { :a=>1, :b=>2 }
      assert_equal( { "a"=>1, "b"=>2 }, foo.stringify_keys!  )
      assert_equal( { "a"=>1, "b"=>2 }, foo )
    end

  end

=end
