-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
yaml.cr
141 lines (133 loc) · 3.48 KB
/
yaml.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
require "./yaml/*"
# The YAML module provides serialization and deserialization of YAML to/from native Crystal data structures.
#
# ### Parsing with `#parse` and `#parse_all`
#
# `YAML#parse` will return an `Any`, which is a convenient wrapper around all possible YAML types,
# making it easy to traverse a complex YAML structure but requires some casts from time to time,
# mostly via some method invocations.
#
# ```
# require "yaml"
#
# data = YAML.parse <<-END
# ---
# foo:
# bar:
# baz:
# - qux
# - fox
# END
# data["foo"]["bar"]["baz"][1].as_s # => "fox"
# ```
#
# ### Parsing with `YAML#mapping`
#
# `YAML#mapping` defines how an object is mapped to YAML. Mapped data is accessible
# through generated properties like *Foo#bar*. It is more type-safe and efficient.
#
# ### Generating with `YAML.build`
#
# Use `YAML.build`, which uses `YAML::Builder`, to generate YAML
# by emitting scalars, sequences and mappings:
#
# ```
# require "yaml"
#
# string = YAML.build do |yaml|
# yaml.mapping do
# yaml.scalar "foo"
# yaml.sequence do
# yaml.scalar 1
# yaml.scalar 2
# end
# end
# end
# string # => "---\nfoo:\n- 1\n- 2\n"
# ```
#
# ### Dumping with `YAML.dump` or `#to_yaml`
#
# `YAML.dump` generates the YAML representation for an object. An `IO` can be passed and it will be written there,
# otherwise it will be returned as a string. Similarly, `#to_yaml` (with or without an `IO`) on any object does the same.
#
# ```
# yaml = YAML.dump({hello: "world"}) # => "---\nhello: world\n"
# File.open("foo.yml", "w") { |f| YAML.dump({hello: "world"}, f) } # writes it to the file
# # or:
# yaml = {hello: "world"}.to_yaml # => "---\nhello: world\n"
# File.open("foo.yml", "w") { |f| {hello: "world"}.to_yaml(f) } # writes it to the file
# ```
module YAML
class Error < Exception
end
# Exception thrown on a YAML parse error.
class ParseException < Error
getter line_number : Int32
getter column_number : Int32
def initialize(message, line_number, column_number)
@line_number = line_number.to_i
@column_number = column_number.to_i
super(message)
end
end
# All valid YAML types.
alias Type = String | Hash(Type, Type) | Array(Type) | Nil
alias EventKind = LibYAML::EventType
# Deserializes a YAML document.
#
# ```yaml
# # ./foo.yml
# data:
# string: "foobar"
# array:
# - John
# - Sarah
# hash: {key: value}
# paragraph: |
# foo
# bar
# ```
#
# ```
# require "yaml"
#
# YAML.parse(File.read("./foo.yml"))
# # => {
# # => "data" => {
# # => "string" => "foobar",
# # => "array" => ["John", "Sarah"],
# # => "hash" => {"key" => "value"},
# # => "paragraph" => "foo\nbar\n"
# # => }
# ```
def self.parse(data : String | IO) : Any
YAML::Parser.new data, &.parse
end
# Deserializes multiple YAML documents.
#
# ```yaml
# # ./foo.yml
# foo: bar
# ---
# hello: world
# ```
#
# ```
# require "yaml"
#
# YAML.parse_all(File.read("./foo.yml"))
# # => [{"foo" => "bar"}, {"hello" => "world"}]
# ```
def self.parse_all(data : String) : Array(Any)
YAML::Parser.new data, &.parse_all
end
# Serializes an object to YAML, returning it as a `String`.
def self.dump(object) : String
object.to_yaml
end
# Serializes an object to YAML, writing it to *io*.
def self.dump(object, io : IO)
object.to_yaml(io)
end
end