diff options
author | Robert Schulze <[email protected]> | 2023-02-23 13:38:54 +0100 |
---|---|---|
committer | git <[email protected]> | 2024-01-18 17:32:34 +0000 |
commit | d3b07b984545ce156e02e9f71404b652c6cb5284 (patch) | |
tree | db319e0f29d7719d4d19ac4722ad09b049cf351b | |
parent | 00814fd6724fff66a10966f5be10ea6dae06c616 (diff) |
[ruby/psych] Add :stringify_names option to convert symbol keys to string for dumping
https://github.com/ruby/psych/commit/3d051d89aa
-rw-r--r-- | ext/psych/lib/psych.rb | 14 | ||||
-rw-r--r-- | ext/psych/lib/psych/visitors/yaml_tree.rb | 5 | ||||
-rw-r--r-- | test/psych/test_psych.rb | 26 | ||||
-rw-r--r-- | test/psych/test_set.rb | 7 |
4 files changed, 50 insertions, 2 deletions
diff --git a/ext/psych/lib/psych.rb b/ext/psych/lib/psych.rb index ae167472f2..d87bd9040a 100644 --- a/ext/psych/lib/psych.rb +++ b/ext/psych/lib/psych.rb @@ -489,6 +489,10 @@ module Psych # # Default: <tt>false</tt>. # + # [<tt>:stringify_names</tt>] Dump symbol keys in Hash objects as string. + # + # Default: <tt>false</tt>. + # # Example: # # # Dump an array, get back a YAML string @@ -502,6 +506,9 @@ module Psych # # # Dump an array to an IO with indentation set # Psych.dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" def self.dump o, io = nil, options = {} if Hash === io options = io @@ -562,6 +569,10 @@ module Psych # # Default: <tt>false</tt>. # + # [<tt>:stringify_names</tt>] Dump symbol keys in Hash objects as string. + # + # Default: <tt>false</tt>. + # # Example: # # # Dump an array, get back a YAML string @@ -575,6 +586,9 @@ module Psych # # # Dump an array to an IO with indentation set # Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" def self.safe_dump o, io = nil, options = {} if Hash === io options = io diff --git a/ext/psych/lib/psych/visitors/yaml_tree.rb b/ext/psych/lib/psych/visitors/yaml_tree.rb index 318f5f892b..a2ebc4d781 100644 --- a/ext/psych/lib/psych/visitors/yaml_tree.rb +++ b/ext/psych/lib/psych/visitors/yaml_tree.rb @@ -65,6 +65,7 @@ module Psych fail(ArgumentError, "Invalid line_width #{@line_width}, must be non-negative or -1 for unlimited.") end end + @stringify_names = options[:stringify_names] @coders = [] @dispatch_cache = Hash.new do |h,klass| @@ -323,7 +324,7 @@ module Psych if o.class == ::Hash register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end @emitter.end_mapping @@ -336,7 +337,7 @@ module Psych register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) o.each do |k,v| - accept k + accept(@stringify_names && Symbol === k ? k.to_s : k) accept v end diff --git a/test/psych/test_psych.rb b/test/psych/test_psych.rb index c977e799e3..42586a8779 100644 --- a/test/psych/test_psych.rb +++ b/test/psych/test_psych.rb @@ -430,6 +430,32 @@ eoyml assert_match(/\A--- :foo\n(?:\.\.\.\n)?\z/, Psych.safe_dump(:foo, permitted_symbols: [:foo])) end + def test_safe_dump_stringify_names + yaml = <<-eoyml +--- +foo: + bar: bar + 'no': special escapes + 123: number +eoyml + + payload = Psych.safe_dump({ + foo: { + bar: "bar", + no: "special escapes", + 123 => "number" + } + }, stringify_names: true) + assert_equal yaml, payload + + assert_equal("---\nfoo: :bar\n", Psych.safe_dump({foo: :bar}, stringify_names: true, permitted_symbols: [:bar])) + + error = assert_raise Psych::DisallowedClass do + Psych.safe_dump({foo: :bar}, stringify_names: true) + end + assert_equal "Tried to dump unspecified class: Symbol(:bar)", error.message + end + def test_safe_dump_aliases x = [] x << x diff --git a/test/psych/test_set.rb b/test/psych/test_set.rb index 87944d839e..b4968d3425 100644 --- a/test/psych/test_set.rb +++ b/test/psych/test_set.rb @@ -46,5 +46,12 @@ bar: baz @set['self'] = @set assert_cycle(@set) end + + def test_stringify_names + @set[:symbol] = :value + + assert_match(/^:symbol: :value/, Psych.dump(@set)) + assert_match(/^symbol: :value/, Psych.dump(@set, stringify_names: true)) + end end end |