psych 2.2.1 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CONTRIBUTING.md +24 -0
- data/{ext/psych/yaml/LICENSE → LICENSE} +9 -7
- data/README.md +13 -13
- data/ext/psych/depend +14 -0
- data/ext/psych/extconf.rb +43 -29
- data/ext/psych/psych.c +6 -3
- data/ext/psych/psych_emitter.c +10 -9
- data/ext/psych/psych_parser.c +69 -72
- data/ext/psych/psych_yaml_tree.c +0 -12
- data/lib/psych/class_loader.rb +11 -9
- data/lib/psych/coder.rb +1 -1
- data/lib/psych/core_ext.rb +3 -20
- data/lib/psych/exception.rb +17 -3
- data/lib/psych/handler.rb +8 -3
- data/lib/psych/handlers/document_stream.rb +2 -2
- data/lib/psych/handlers/recorder.rb +2 -2
- data/lib/psych/json/ruby_events.rb +1 -1
- data/lib/psych/json/stream.rb +3 -3
- data/lib/psych/json/tree_builder.rb +2 -2
- data/lib/psych/json/yaml_events.rb +1 -1
- data/lib/psych/nodes/alias.rb +3 -1
- data/lib/psych/nodes/document.rb +3 -1
- data/lib/psych/nodes/mapping.rb +3 -1
- data/lib/psych/nodes/node.rb +24 -5
- data/lib/psych/nodes/scalar.rb +4 -2
- data/lib/psych/nodes/sequence.rb +3 -1
- data/lib/psych/nodes/stream.rb +3 -1
- data/lib/psych/nodes.rb +8 -8
- data/lib/psych/omap.rb +1 -1
- data/lib/psych/parser.rb +14 -1
- data/lib/psych/scalar_scanner.rb +39 -47
- data/lib/psych/set.rb +1 -1
- data/lib/psych/stream.rb +1 -1
- data/lib/psych/streaming.rb +1 -1
- data/lib/psych/syntax_error.rb +2 -2
- data/lib/psych/tree_builder.rb +48 -8
- data/lib/psych/versions.rb +5 -4
- data/lib/psych/visitors/depth_first.rb +1 -1
- data/lib/psych/visitors/emitter.rb +1 -1
- data/lib/psych/visitors/json_tree.rb +2 -2
- data/lib/psych/visitors/to_ruby.rb +61 -31
- data/lib/psych/visitors/visitor.rb +18 -4
- data/lib/psych/visitors/yaml_tree.rb +111 -123
- data/lib/psych/visitors.rb +7 -7
- data/lib/psych/y.rb +1 -1
- data/lib/psych.rb +333 -96
- metadata +16 -52
- data/.gitignore +0 -14
- data/.travis.yml +0 -18
- data/CHANGELOG.rdoc +0 -576
- data/Gemfile +0 -3
- data/Mavenfile +0 -7
- data/Rakefile +0 -33
- data/bin/console +0 -7
- data/bin/setup +0 -6
- data/ext/psych/.gitignore +0 -11
- data/ext/psych/yaml/api.c +0 -1392
- data/ext/psych/yaml/config.h +0 -10
- data/ext/psych/yaml/dumper.c +0 -394
- data/ext/psych/yaml/emitter.c +0 -2329
- data/ext/psych/yaml/loader.c +0 -444
- data/ext/psych/yaml/parser.c +0 -1374
- data/ext/psych/yaml/reader.c +0 -469
- data/ext/psych/yaml/scanner.c +0 -3576
- data/ext/psych/yaml/writer.c +0 -141
- data/ext/psych/yaml/yaml.h +0 -1971
- data/ext/psych/yaml/yaml_private.h +0 -662
- data/lib/psych/deprecated.rb +0 -86
- data/psych.gemspec +0 -43
data/lib/psych.rb
CHANGED
@@ -1,35 +1,39 @@
|
|
1
|
-
# frozen_string_literal:
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require_relative 'psych/versions'
|
3
3
|
case RUBY_ENGINE
|
4
4
|
when 'jruby'
|
5
|
-
|
6
|
-
|
5
|
+
require_relative 'psych_jars'
|
6
|
+
if JRuby::Util.respond_to?(:load_ext)
|
7
|
+
JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
|
8
|
+
else
|
9
|
+
require 'java'; require 'jruby'
|
10
|
+
org.jruby.ext.psych.PsychLibrary.new.load(JRuby.runtime, false)
|
11
|
+
end
|
7
12
|
else
|
8
13
|
require 'psych.so'
|
9
14
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
require 'psych/class_loader'
|
15
|
+
require_relative 'psych/nodes'
|
16
|
+
require_relative 'psych/streaming'
|
17
|
+
require_relative 'psych/visitors'
|
18
|
+
require_relative 'psych/handler'
|
19
|
+
require_relative 'psych/tree_builder'
|
20
|
+
require_relative 'psych/parser'
|
21
|
+
require_relative 'psych/omap'
|
22
|
+
require_relative 'psych/set'
|
23
|
+
require_relative 'psych/coder'
|
24
|
+
require_relative 'psych/core_ext'
|
25
|
+
require_relative 'psych/stream'
|
26
|
+
require_relative 'psych/json/tree_builder'
|
27
|
+
require_relative 'psych/json/stream'
|
28
|
+
require_relative 'psych/handlers/document_stream'
|
29
|
+
require_relative 'psych/class_loader'
|
26
30
|
|
27
31
|
###
|
28
32
|
# = Overview
|
29
33
|
#
|
30
34
|
# Psych is a YAML parser and emitter.
|
31
|
-
# Psych leverages libyaml [Home page:
|
32
|
-
# or [
|
35
|
+
# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
|
36
|
+
# or [git repo: https://github.com/yaml/libyaml] for its YAML parsing
|
33
37
|
# and emitting capabilities. In addition to wrapping libyaml, Psych also
|
34
38
|
# knows how to serialize and de-serialize most Ruby objects to and from
|
35
39
|
# the YAML format.
|
@@ -70,12 +74,15 @@ require 'psych/class_loader'
|
|
70
74
|
#
|
71
75
|
# ==== Reading from a string
|
72
76
|
#
|
73
|
-
# Psych.
|
74
|
-
# Psych.
|
77
|
+
# Psych.safe_load("--- a") # => 'a'
|
78
|
+
# Psych.safe_load("---\n - a\n - b") # => ['a', 'b']
|
79
|
+
# # From a trusted string:
|
80
|
+
# Psych.load("--- !ruby/range\nbegin: 0\nend: 42\nexcl: false\n") # => 0..42
|
75
81
|
#
|
76
82
|
# ==== Reading from a file
|
77
83
|
#
|
78
|
-
# Psych.
|
84
|
+
# Psych.safe_load_file("data.yml", permitted_classes: [Date])
|
85
|
+
# Psych.load_file("trusted_database.yml")
|
79
86
|
#
|
80
87
|
# ==== Exception handling
|
81
88
|
#
|
@@ -195,12 +202,13 @@ require 'psych/class_loader'
|
|
195
202
|
#
|
196
203
|
# ==== Receiving an events stream
|
197
204
|
#
|
198
|
-
#
|
205
|
+
# recorder = Psych::Handlers::Recorder.new
|
206
|
+
# parser = Psych::Parser.new(recorder)
|
199
207
|
#
|
200
208
|
# parser.parse("---\n - a\n - b")
|
201
|
-
#
|
202
|
-
#
|
203
|
-
#
|
209
|
+
# recorder.events # => [list of [event, args] lists]
|
210
|
+
# # event is one of: Psych::Handler::EVENTS
|
211
|
+
# # args are the arguments passed to the event
|
204
212
|
#
|
205
213
|
# === Emitting
|
206
214
|
#
|
@@ -225,32 +233,45 @@ require 'psych/class_loader'
|
|
225
233
|
|
226
234
|
module Psych
|
227
235
|
# The version of libyaml Psych is using
|
228
|
-
LIBYAML_VERSION = Psych.libyaml_version.join
|
229
|
-
|
230
|
-
FALLBACK = Struct.new :to_ruby # :nodoc:
|
236
|
+
LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
|
231
237
|
|
232
238
|
###
|
233
239
|
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
234
240
|
# provided, the object contained in the first document will be returned.
|
235
|
-
# +filename+ will be used in the exception message if any exception
|
236
|
-
# while parsing.
|
241
|
+
# +filename+ will be used in the exception message if any exception
|
242
|
+
# is raised while parsing. If +yaml+ is empty, it returns
|
243
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
237
244
|
#
|
238
245
|
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
239
246
|
#
|
240
247
|
# Example:
|
241
248
|
#
|
242
|
-
# Psych.
|
243
|
-
# Psych.
|
249
|
+
# Psych.unsafe_load("--- a") # => 'a'
|
250
|
+
# Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b']
|
244
251
|
#
|
245
252
|
# begin
|
246
|
-
# Psych.
|
253
|
+
# Psych.unsafe_load("--- `", filename: "file.txt")
|
247
254
|
# rescue Psych::SyntaxError => ex
|
248
255
|
# ex.file # => 'file.txt'
|
249
256
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
250
257
|
# end
|
251
|
-
|
252
|
-
|
253
|
-
|
258
|
+
#
|
259
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
260
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
261
|
+
#
|
262
|
+
# Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
263
|
+
# Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
264
|
+
#
|
265
|
+
# Raises a TypeError when `yaml` parameter is NilClass
|
266
|
+
#
|
267
|
+
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
268
|
+
# YAML documents that are supplied via user input. Instead, please use the
|
269
|
+
# load method or the safe_load method.
|
270
|
+
#
|
271
|
+
def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false
|
272
|
+
result = parse(yaml, filename: filename)
|
273
|
+
return fallback unless result
|
274
|
+
result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer)
|
254
275
|
end
|
255
276
|
|
256
277
|
###
|
@@ -260,46 +281,99 @@ module Psych
|
|
260
281
|
# * TrueClass
|
261
282
|
# * FalseClass
|
262
283
|
# * NilClass
|
263
|
-
# *
|
284
|
+
# * Integer
|
285
|
+
# * Float
|
264
286
|
# * String
|
265
287
|
# * Array
|
266
288
|
# * Hash
|
267
289
|
#
|
268
290
|
# Recursive data structures are not allowed by default. Arbitrary classes
|
269
|
-
# can be allowed by adding those classes to the +
|
291
|
+
# can be allowed by adding those classes to the +permitted_classes+ keyword argument. They are
|
270
292
|
# additive. For example, to allow Date deserialization:
|
271
293
|
#
|
272
|
-
# Psych.safe_load(yaml, [Date])
|
294
|
+
# Psych.safe_load(yaml, permitted_classes: [Date])
|
273
295
|
#
|
274
296
|
# Now the Date class can be loaded in addition to the classes listed above.
|
275
297
|
#
|
276
|
-
# Aliases can be explicitly allowed by changing the +aliases+
|
298
|
+
# Aliases can be explicitly allowed by changing the +aliases+ keyword argument.
|
277
299
|
# For example:
|
278
300
|
#
|
279
301
|
# x = []
|
280
302
|
# x << x
|
281
303
|
# yaml = Psych.dump x
|
282
304
|
# Psych.safe_load yaml # => raises an exception
|
283
|
-
# Psych.safe_load yaml,
|
305
|
+
# Psych.safe_load yaml, aliases: true # => loads the aliases
|
284
306
|
#
|
285
307
|
# A Psych::DisallowedClass exception will be raised if the yaml contains a
|
286
|
-
# class that isn't in the
|
287
|
-
#
|
288
|
-
# A Psych::
|
289
|
-
# but the +aliases+
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
308
|
+
# class that isn't in the +permitted_classes+ list.
|
309
|
+
#
|
310
|
+
# A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases
|
311
|
+
# but the +aliases+ keyword argument is set to false.
|
312
|
+
#
|
313
|
+
# +filename+ will be used in the exception message if any exception is raised
|
314
|
+
# while parsing.
|
315
|
+
#
|
316
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
317
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
318
|
+
#
|
319
|
+
# Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
320
|
+
# Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
321
|
+
#
|
322
|
+
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
|
323
|
+
result = parse(yaml, filename: filename)
|
324
|
+
return fallback unless result
|
325
|
+
|
326
|
+
class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s),
|
327
|
+
permitted_symbols.map(&:to_s))
|
328
|
+
scanner = ScalarScanner.new class_loader, strict_integer: strict_integer
|
329
|
+
visitor = if aliases
|
330
|
+
Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
|
331
|
+
else
|
332
|
+
Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze
|
333
|
+
end
|
334
|
+
result = visitor.accept result
|
335
|
+
result
|
336
|
+
end
|
337
|
+
|
338
|
+
###
|
339
|
+
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
340
|
+
# provided, the object contained in the first document will be returned.
|
341
|
+
# +filename+ will be used in the exception message if any exception
|
342
|
+
# is raised while parsing. If +yaml+ is empty, it returns
|
343
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
344
|
+
#
|
345
|
+
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
346
|
+
#
|
347
|
+
# Example:
|
348
|
+
#
|
349
|
+
# Psych.load("--- a") # => 'a'
|
350
|
+
# Psych.load("---\n - a\n - b") # => ['a', 'b']
|
351
|
+
#
|
352
|
+
# begin
|
353
|
+
# Psych.load("--- `", filename: "file.txt")
|
354
|
+
# rescue Psych::SyntaxError => ex
|
355
|
+
# ex.file # => 'file.txt'
|
356
|
+
# ex.message # => "(file.txt): found character that cannot start any token"
|
357
|
+
# end
|
358
|
+
#
|
359
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
360
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
361
|
+
#
|
362
|
+
# Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
|
363
|
+
# Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
364
|
+
#
|
365
|
+
# Raises a TypeError when `yaml` parameter is NilClass. This method is
|
366
|
+
# similar to `safe_load` except that `Symbol` objects are allowed by default.
|
367
|
+
#
|
368
|
+
def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false
|
369
|
+
safe_load yaml, permitted_classes: permitted_classes,
|
370
|
+
permitted_symbols: permitted_symbols,
|
371
|
+
aliases: aliases,
|
372
|
+
filename: filename,
|
373
|
+
fallback: fallback,
|
374
|
+
symbolize_names: symbolize_names,
|
375
|
+
freeze: freeze,
|
376
|
+
strict_integer: strict_integer
|
303
377
|
end
|
304
378
|
|
305
379
|
###
|
@@ -314,28 +388,30 @@ module Psych
|
|
314
388
|
# Psych.parse("---\n - a\n - b") # => #<Psych::Nodes::Document:0x00>
|
315
389
|
#
|
316
390
|
# begin
|
317
|
-
# Psych.parse("--- `", "file.txt")
|
391
|
+
# Psych.parse("--- `", filename: "file.txt")
|
318
392
|
# rescue Psych::SyntaxError => ex
|
319
393
|
# ex.file # => 'file.txt'
|
320
394
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
321
395
|
# end
|
322
396
|
#
|
323
397
|
# See Psych::Nodes for more information about YAML AST.
|
324
|
-
def self.parse yaml, filename
|
325
|
-
parse_stream(yaml, filename) do |node|
|
398
|
+
def self.parse yaml, filename: nil
|
399
|
+
parse_stream(yaml, filename: filename) do |node|
|
326
400
|
return node
|
327
401
|
end
|
328
|
-
|
402
|
+
|
403
|
+
false
|
329
404
|
end
|
330
405
|
|
331
406
|
###
|
332
407
|
# Parse a file at +filename+. Returns the Psych::Nodes::Document.
|
333
408
|
#
|
334
409
|
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
335
|
-
def self.parse_file filename
|
336
|
-
File.open filename, 'r:bom|utf-8' do |f|
|
337
|
-
parse f, filename
|
410
|
+
def self.parse_file filename, fallback: false
|
411
|
+
result = File.open filename, 'r:bom|utf-8' do |f|
|
412
|
+
parse f, filename: filename
|
338
413
|
end
|
414
|
+
result || fallback
|
339
415
|
end
|
340
416
|
|
341
417
|
###
|
@@ -364,14 +440,16 @@ module Psych
|
|
364
440
|
# end
|
365
441
|
#
|
366
442
|
# begin
|
367
|
-
# Psych.parse_stream("--- `", "file.txt")
|
443
|
+
# Psych.parse_stream("--- `", filename: "file.txt")
|
368
444
|
# rescue Psych::SyntaxError => ex
|
369
445
|
# ex.file # => 'file.txt'
|
370
446
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
371
447
|
# end
|
372
448
|
#
|
449
|
+
# Raises a TypeError when NilClass is passed.
|
450
|
+
#
|
373
451
|
# See Psych::Nodes for more information about YAML AST.
|
374
|
-
def self.parse_stream yaml, filename
|
452
|
+
def self.parse_stream yaml, filename: nil, &block
|
375
453
|
if block_given?
|
376
454
|
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
|
377
455
|
parser.parse yaml, filename
|
@@ -393,6 +471,24 @@ module Psych
|
|
393
471
|
# to control the output format. If an IO object is passed in, the YAML will
|
394
472
|
# be dumped to that IO object.
|
395
473
|
#
|
474
|
+
# Currently supported options are:
|
475
|
+
#
|
476
|
+
# [<tt>:indentation</tt>] Number of space characters used to indent.
|
477
|
+
# Acceptable value should be in <tt>0..9</tt> range,
|
478
|
+
# otherwise option is ignored.
|
479
|
+
#
|
480
|
+
# Default: <tt>2</tt>.
|
481
|
+
# [<tt>:line_width</tt>] Max character to wrap line at.
|
482
|
+
#
|
483
|
+
# Default: <tt>0</tt> (meaning "wrap at 81").
|
484
|
+
# [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
|
485
|
+
# strictly formal).
|
486
|
+
#
|
487
|
+
# Default: <tt>false</tt>.
|
488
|
+
# [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
|
489
|
+
#
|
490
|
+
# Default: <tt>false</tt>.
|
491
|
+
#
|
396
492
|
# Example:
|
397
493
|
#
|
398
494
|
# # Dump an array, get back a YAML string
|
@@ -402,10 +498,10 @@ module Psych
|
|
402
498
|
# Psych.dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
|
403
499
|
#
|
404
500
|
# # Dump an array with indentation set
|
405
|
-
# Psych.dump(['a', ['b']], :
|
501
|
+
# Psych.dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
|
406
502
|
#
|
407
503
|
# # Dump an array to an IO with indentation set
|
408
|
-
# Psych.dump(['a', ['b']], StringIO.new, :
|
504
|
+
# Psych.dump(['a', ['b']], StringIO.new, indentation: 3)
|
409
505
|
def self.dump o, io = nil, options = {}
|
410
506
|
if Hash === io
|
411
507
|
options = io
|
@@ -417,6 +513,79 @@ module Psych
|
|
417
513
|
visitor.tree.yaml io, options
|
418
514
|
end
|
419
515
|
|
516
|
+
###
|
517
|
+
# call-seq:
|
518
|
+
# Psych.safe_dump(o) -> string of yaml
|
519
|
+
# Psych.safe_dump(o, options) -> string of yaml
|
520
|
+
# Psych.safe_dump(o, io) -> io object passed in
|
521
|
+
# Psych.safe_dump(o, io, options) -> io object passed in
|
522
|
+
#
|
523
|
+
# Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
|
524
|
+
# to control the output format. If an IO object is passed in, the YAML will
|
525
|
+
# be dumped to that IO object. By default, only the following
|
526
|
+
# classes are allowed to be serialized:
|
527
|
+
#
|
528
|
+
# * TrueClass
|
529
|
+
# * FalseClass
|
530
|
+
# * NilClass
|
531
|
+
# * Integer
|
532
|
+
# * Float
|
533
|
+
# * String
|
534
|
+
# * Array
|
535
|
+
# * Hash
|
536
|
+
#
|
537
|
+
# Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
|
538
|
+
# keyword argument. They are additive. For example, to allow Date serialization:
|
539
|
+
#
|
540
|
+
# Psych.safe_dump(yaml, permitted_classes: [Date])
|
541
|
+
#
|
542
|
+
# Now the Date class can be dumped in addition to the classes listed above.
|
543
|
+
#
|
544
|
+
# A Psych::DisallowedClass exception will be raised if the object contains a
|
545
|
+
# class that isn't in the +permitted_classes+ list.
|
546
|
+
#
|
547
|
+
# Currently supported options are:
|
548
|
+
#
|
549
|
+
# [<tt>:indentation</tt>] Number of space characters used to indent.
|
550
|
+
# Acceptable value should be in <tt>0..9</tt> range,
|
551
|
+
# otherwise option is ignored.
|
552
|
+
#
|
553
|
+
# Default: <tt>2</tt>.
|
554
|
+
# [<tt>:line_width</tt>] Max character to wrap line at.
|
555
|
+
#
|
556
|
+
# Default: <tt>0</tt> (meaning "wrap at 81").
|
557
|
+
# [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
|
558
|
+
# strictly formal).
|
559
|
+
#
|
560
|
+
# Default: <tt>false</tt>.
|
561
|
+
# [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
|
562
|
+
#
|
563
|
+
# Default: <tt>false</tt>.
|
564
|
+
#
|
565
|
+
# Example:
|
566
|
+
#
|
567
|
+
# # Dump an array, get back a YAML string
|
568
|
+
# Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
|
569
|
+
#
|
570
|
+
# # Dump an array to an IO object
|
571
|
+
# Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
|
572
|
+
#
|
573
|
+
# # Dump an array with indentation set
|
574
|
+
# Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
|
575
|
+
#
|
576
|
+
# # Dump an array to an IO with indentation set
|
577
|
+
# Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
|
578
|
+
def self.safe_dump o, io = nil, options = {}
|
579
|
+
if Hash === io
|
580
|
+
options = io
|
581
|
+
io = nil
|
582
|
+
end
|
583
|
+
|
584
|
+
visitor = Psych::Visitors::RestrictedYAMLTree.create options
|
585
|
+
visitor << o
|
586
|
+
visitor.tree.yaml io, options
|
587
|
+
end
|
588
|
+
|
420
589
|
###
|
421
590
|
# Dump a list of objects as separate documents to a document stream.
|
422
591
|
#
|
@@ -454,55 +623,123 @@ module Psych
|
|
454
623
|
# end
|
455
624
|
# list # => ['foo', 'bar']
|
456
625
|
#
|
457
|
-
def self.load_stream yaml, filename
|
458
|
-
if block_given?
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
626
|
+
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
|
627
|
+
result = if block_given?
|
628
|
+
parse_stream(yaml, filename: filename) do |node|
|
629
|
+
yield node.to_ruby(**kwargs)
|
630
|
+
end
|
631
|
+
else
|
632
|
+
parse_stream(yaml, filename: filename).children.map { |node| node.to_ruby(**kwargs) }
|
633
|
+
end
|
634
|
+
|
635
|
+
return fallback if result.is_a?(Array) && result.empty?
|
636
|
+
result
|
465
637
|
end
|
466
638
|
|
467
639
|
###
|
468
640
|
# Load the document contained in +filename+. Returns the yaml contained in
|
469
641
|
# +filename+ as a Ruby object, or if the file is empty, it returns
|
470
|
-
# the specified
|
471
|
-
|
642
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
643
|
+
#
|
644
|
+
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
645
|
+
# YAML documents that are supplied via user input. Instead, please use the
|
646
|
+
# safe_load_file method.
|
647
|
+
def self.unsafe_load_file filename, **kwargs
|
648
|
+
File.open(filename, 'r:bom|utf-8') { |f|
|
649
|
+
self.unsafe_load f, filename: filename, **kwargs
|
650
|
+
}
|
651
|
+
end
|
652
|
+
|
653
|
+
###
|
654
|
+
# Safely loads the document contained in +filename+. Returns the yaml contained in
|
655
|
+
# +filename+ as a Ruby object, or if the file is empty, it returns
|
656
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
657
|
+
# See safe_load for options.
|
658
|
+
def self.safe_load_file filename, **kwargs
|
472
659
|
File.open(filename, 'r:bom|utf-8') { |f|
|
473
|
-
self.
|
660
|
+
self.safe_load f, filename: filename, **kwargs
|
661
|
+
}
|
662
|
+
end
|
663
|
+
|
664
|
+
###
|
665
|
+
# Loads the document contained in +filename+. Returns the yaml contained in
|
666
|
+
# +filename+ as a Ruby object, or if the file is empty, it returns
|
667
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
668
|
+
# See load for options.
|
669
|
+
def self.load_file filename, **kwargs
|
670
|
+
File.open(filename, 'r:bom|utf-8') { |f|
|
671
|
+
self.load f, filename: filename, **kwargs
|
474
672
|
}
|
475
673
|
end
|
476
674
|
|
477
675
|
# :stopdoc:
|
478
|
-
@domain_types = {}
|
479
676
|
def self.add_domain_type domain, type_tag, &block
|
480
677
|
key = ['tag', domain, type_tag].join ':'
|
481
|
-
|
482
|
-
|
678
|
+
domain_types[key] = [key, block]
|
679
|
+
domain_types["tag:#{type_tag}"] = [key, block]
|
483
680
|
end
|
484
681
|
|
485
682
|
def self.add_builtin_type type_tag, &block
|
486
683
|
domain = 'yaml.org,2002'
|
487
684
|
key = ['tag', domain, type_tag].join ':'
|
488
|
-
|
685
|
+
domain_types[key] = [key, block]
|
489
686
|
end
|
490
687
|
|
491
688
|
def self.remove_type type_tag
|
492
|
-
|
689
|
+
domain_types.delete type_tag
|
493
690
|
end
|
494
691
|
|
495
|
-
@load_tags = {}
|
496
|
-
@dump_tags = {}
|
497
692
|
def self.add_tag tag, klass
|
498
|
-
|
499
|
-
|
693
|
+
load_tags[tag] = klass.name
|
694
|
+
dump_tags[klass] = tag
|
500
695
|
end
|
501
696
|
|
502
697
|
class << self
|
503
|
-
|
504
|
-
|
505
|
-
|
698
|
+
if defined?(Ractor)
|
699
|
+
class Config
|
700
|
+
attr_accessor :load_tags, :dump_tags, :domain_types
|
701
|
+
def initialize
|
702
|
+
@load_tags = {}
|
703
|
+
@dump_tags = {}
|
704
|
+
@domain_types = {}
|
705
|
+
end
|
706
|
+
end
|
707
|
+
|
708
|
+
def config
|
709
|
+
Ractor.current[:PsychConfig] ||= Config.new
|
710
|
+
end
|
711
|
+
|
712
|
+
def load_tags
|
713
|
+
config.load_tags
|
714
|
+
end
|
715
|
+
|
716
|
+
def dump_tags
|
717
|
+
config.dump_tags
|
718
|
+
end
|
719
|
+
|
720
|
+
def domain_types
|
721
|
+
config.domain_types
|
722
|
+
end
|
723
|
+
|
724
|
+
def load_tags=(value)
|
725
|
+
config.load_tags = value
|
726
|
+
end
|
727
|
+
|
728
|
+
def dump_tags=(value)
|
729
|
+
config.dump_tags = value
|
730
|
+
end
|
731
|
+
|
732
|
+
def domain_types=(value)
|
733
|
+
config.domain_types = value
|
734
|
+
end
|
735
|
+
else
|
736
|
+
attr_accessor :load_tags
|
737
|
+
attr_accessor :dump_tags
|
738
|
+
attr_accessor :domain_types
|
739
|
+
end
|
506
740
|
end
|
741
|
+
self.load_tags = {}
|
742
|
+
self.dump_tags = {}
|
743
|
+
self.domain_types = {}
|
507
744
|
# :startdoc:
|
508
745
|
end
|