[ruby/psych] Add :stringify_names option to convert symbol keys to string for dumping

https://github.com/ruby/psych/commit/3d051d89aa
This commit is contained in:
Robert Schulze 2023-02-23 13:38:54 +01:00 коммит произвёл git
Родитель 00814fd672
Коммит d3b07b9845
4 изменённых файлов: 50 добавлений и 2 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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