syck 1.0.0
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.
- data/.autotest.erb +8 -0
- data/.gemtest +0 -0
- data/CHANGELOG.rdoc +6 -0
- data/Manifest.txt +52 -0
- data/README.rdoc +51 -0
- data/Rakefile +32 -0
- data/ext/syck/bytecode.c +1165 -0
- data/ext/syck/emitter.c +1247 -0
- data/ext/syck/extconf.h +3 -0
- data/ext/syck/extconf.rb +5 -0
- data/ext/syck/gram.c +1894 -0
- data/ext/syck/gram.h +79 -0
- data/ext/syck/handler.c +173 -0
- data/ext/syck/implicit.c +2990 -0
- data/ext/syck/node.c +407 -0
- data/ext/syck/rubyext.c +2328 -0
- data/ext/syck/syck.c +524 -0
- data/ext/syck/syck.h +453 -0
- data/ext/syck/token.c +2724 -0
- data/ext/syck/yaml2byte.c +259 -0
- data/ext/syck/yamlbyte.h +171 -0
- data/lib/syck.bundle +0 -0
- data/lib/syck.rb +447 -0
- data/lib/syck/baseemitter.rb +242 -0
- data/lib/syck/basenode.rb +222 -0
- data/lib/syck/constants.rb +45 -0
- data/lib/syck/encoding.rb +35 -0
- data/lib/syck/error.rb +34 -0
- data/lib/syck/loader.rb +14 -0
- data/lib/syck/rubytypes.rb +450 -0
- data/lib/syck/stream.rb +41 -0
- data/lib/syck/stringio.rb +85 -0
- data/lib/syck/syck.rb +16 -0
- data/lib/syck/tag.rb +95 -0
- data/lib/syck/types.rb +192 -0
- data/lib/syck/yamlnode.rb +54 -0
- data/lib/syck/ypath.rb +54 -0
- data/lib/yaml/syck.rb +14 -0
- data/test/helper.rb +2 -0
- data/test/test_array.rb +13 -0
- data/test/test_boolean.rb +36 -0
- data/test/test_class.rb +11 -0
- data/test/test_exception.rb +45 -0
- data/test/test_hash.rb +24 -0
- data/test/test_null.rb +19 -0
- data/test/test_omap.rb +55 -0
- data/test/test_set.rb +30 -0
- data/test/test_string.rb +44 -0
- data/test/test_struct.rb +32 -0
- data/test/test_symbol.rb +21 -0
- data/test/test_time.rb +23 -0
- data/test/test_yaml.rb +1403 -0
- data/test/test_yaml_properties.rb +63 -0
- metadata +187 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# Constants used throughout the library
|
3
|
+
#
|
4
|
+
module Syck
|
5
|
+
|
6
|
+
#
|
7
|
+
# Constants
|
8
|
+
#
|
9
|
+
VERSION = '1.0.0'
|
10
|
+
SUPPORTED_YAML_VERSIONS = ['1.0']
|
11
|
+
|
12
|
+
#
|
13
|
+
# Parser tokens
|
14
|
+
#
|
15
|
+
WORD_CHAR = 'A-Za-z0-9'
|
16
|
+
PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
|
17
|
+
NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
|
18
|
+
ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]'
|
19
|
+
INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
|
20
|
+
SPACE_INDICATORS = '-#:,?'
|
21
|
+
RESTRICTED_INDICATORS = '#:,}]'
|
22
|
+
DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
|
23
|
+
DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
|
24
|
+
ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a
|
25
|
+
\x08 \t \n \v \f \r \x0e \x0f
|
26
|
+
\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
|
27
|
+
\x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
|
28
|
+
}
|
29
|
+
UNESCAPES = {
|
30
|
+
'a' => "\x07", 'b' => "\x08", 't' => "\x09",
|
31
|
+
'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
|
32
|
+
'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
|
33
|
+
}
|
34
|
+
|
35
|
+
#
|
36
|
+
# Default settings
|
37
|
+
#
|
38
|
+
DEFAULTS = {
|
39
|
+
:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
|
40
|
+
:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
|
41
|
+
:WidthType => 'absolute', :BestWidth => 80,
|
42
|
+
:UseBlock => false, :UseFold => false, :Encoding => :None
|
43
|
+
}
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# Handle Unicode-to-Internal conversion
|
3
|
+
#
|
4
|
+
|
5
|
+
module Syck
|
6
|
+
|
7
|
+
#
|
8
|
+
# Escape the string, condensing common escapes
|
9
|
+
#
|
10
|
+
def self.escape( value, skip = "" )
|
11
|
+
warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE
|
12
|
+
value.gsub( /\\/, "\\\\\\" ).
|
13
|
+
gsub( /"/, "\\\"" ).
|
14
|
+
gsub( /([\x00-\x1f])/ ) do
|
15
|
+
skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
#
|
20
|
+
# Unescape the condenses escapes
|
21
|
+
#
|
22
|
+
def self.unescape( value )
|
23
|
+
warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE
|
24
|
+
value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
|
25
|
+
if $3
|
26
|
+
["#$3".hex ].pack('U*')
|
27
|
+
elsif $2
|
28
|
+
[$2].pack( "H2" )
|
29
|
+
else
|
30
|
+
UNESCAPES[$1]
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/syck/error.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Error messages and exception class
|
3
|
+
#
|
4
|
+
|
5
|
+
module Syck
|
6
|
+
|
7
|
+
#
|
8
|
+
# Error messages
|
9
|
+
#
|
10
|
+
|
11
|
+
ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
|
12
|
+
ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
|
13
|
+
ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
|
14
|
+
ERROR_MANY_EXPLICIT = "More than one explicit transfer"
|
15
|
+
ERROR_MANY_IMPLICIT = "More than one implicit request"
|
16
|
+
ERROR_NO_ANCHOR = "No anchor for alias '%s'"
|
17
|
+
ERROR_BAD_ANCHOR = "Invalid anchor: %s"
|
18
|
+
ERROR_MANY_ANCHOR = "More than one anchor"
|
19
|
+
ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
|
20
|
+
ERROR_BAD_ALIAS = "Invalid alias: %s"
|
21
|
+
ERROR_MANY_ALIAS = "More than one alias"
|
22
|
+
ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
|
23
|
+
ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
|
24
|
+
ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
|
25
|
+
|
26
|
+
#
|
27
|
+
# YAML Error classes
|
28
|
+
#
|
29
|
+
|
30
|
+
class Error < StandardError; end
|
31
|
+
class ParseError < Error; end
|
32
|
+
class TypeError < StandardError; end
|
33
|
+
|
34
|
+
end
|
data/lib/syck/loader.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# YAML::Loader class
|
3
|
+
# .. type handling ..
|
4
|
+
#
|
5
|
+
module Syck
|
6
|
+
class Loader
|
7
|
+
TRANSFER_DOMAINS = {
|
8
|
+
'yaml.org,2002' => {},
|
9
|
+
'ruby.yaml.org,2002' => {}
|
10
|
+
}
|
11
|
+
PRIVATE_TYPES = {}
|
12
|
+
IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,450 @@
|
|
1
|
+
# -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
class Class
|
5
|
+
def to_yaml( opts = {} )
|
6
|
+
raise TypeError, "can't dump anonymous class %s" % self.class
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Object
|
11
|
+
yaml_as "tag:ruby.yaml.org,2002:object"
|
12
|
+
def to_yaml_style; end
|
13
|
+
undef to_yaml_properties rescue nil
|
14
|
+
def to_yaml_properties; instance_variables.sort; end
|
15
|
+
def to_yaml( opts = {} )
|
16
|
+
Syck::quick_emit( self, opts ) do |out|
|
17
|
+
out.map( taguri, to_yaml_style ) do |map|
|
18
|
+
to_yaml_properties.each do |m|
|
19
|
+
map.add( m[1..-1], instance_variable_get( m ) )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
alias :syck_to_yaml :to_yaml
|
25
|
+
end
|
26
|
+
|
27
|
+
class Hash
|
28
|
+
yaml_as "tag:ruby.yaml.org,2002:hash"
|
29
|
+
yaml_as "tag:yaml.org,2002:map"
|
30
|
+
def yaml_initialize( tag, val )
|
31
|
+
if Array === val
|
32
|
+
update Hash.[]( *val ) # Convert the map to a sequence
|
33
|
+
elsif Hash === val
|
34
|
+
update val
|
35
|
+
else
|
36
|
+
raise Syck::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
|
37
|
+
end
|
38
|
+
end
|
39
|
+
def to_yaml( opts = {} )
|
40
|
+
Syck::quick_emit( self, opts ) do |out|
|
41
|
+
out.map( taguri, to_yaml_style ) do |map|
|
42
|
+
each do |k, v|
|
43
|
+
map.add( k, v )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Struct
|
51
|
+
yaml_as "tag:ruby.yaml.org,2002:struct"
|
52
|
+
def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
|
53
|
+
def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
|
54
|
+
def self.yaml_new( klass, tag, val )
|
55
|
+
if Hash === val
|
56
|
+
struct_type = nil
|
57
|
+
|
58
|
+
#
|
59
|
+
# Use existing Struct if it exists
|
60
|
+
#
|
61
|
+
props = {}
|
62
|
+
val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
|
63
|
+
begin
|
64
|
+
struct_type = Syck.read_type_class( tag, Struct ).last
|
65
|
+
rescue NameError
|
66
|
+
end
|
67
|
+
if not struct_type
|
68
|
+
struct_def = [ tag.split( ':', 4 ).last ]
|
69
|
+
struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Set the Struct properties
|
74
|
+
#
|
75
|
+
st = Syck::object_maker( struct_type, {} )
|
76
|
+
st.members.each do |m|
|
77
|
+
st.send( "#{m}=", val[m.to_s] )
|
78
|
+
end
|
79
|
+
props.each do |k,v|
|
80
|
+
st.instance_variable_set(k, v)
|
81
|
+
end
|
82
|
+
st
|
83
|
+
else
|
84
|
+
raise Syck::TypeError, "Invalid Ruby Struct: " + val.inspect
|
85
|
+
end
|
86
|
+
end
|
87
|
+
def to_yaml( opts = {} )
|
88
|
+
Syck::quick_emit( self, opts ) do |out|
|
89
|
+
#
|
90
|
+
# Basic struct is passed as a YAML map
|
91
|
+
#
|
92
|
+
out.map( taguri, to_yaml_style ) do |map|
|
93
|
+
self.members.each do |m|
|
94
|
+
map.add( m.to_s, self[m.to_s] )
|
95
|
+
end
|
96
|
+
self.to_yaml_properties.each do |m|
|
97
|
+
map.add( m, instance_variable_get( m ) )
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class Array
|
105
|
+
yaml_as "tag:ruby.yaml.org,2002:array"
|
106
|
+
yaml_as "tag:yaml.org,2002:seq"
|
107
|
+
def yaml_initialize( tag, val ); concat( val.to_a ); end
|
108
|
+
def to_yaml( opts = {} )
|
109
|
+
Syck::quick_emit( self, opts ) do |out|
|
110
|
+
out.seq( taguri, to_yaml_style ) do |seq|
|
111
|
+
each do |x|
|
112
|
+
seq.add( x )
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class Exception
|
120
|
+
yaml_as "tag:ruby.yaml.org,2002:exception"
|
121
|
+
def Exception.yaml_new( klass, tag, val )
|
122
|
+
o = klass.allocate
|
123
|
+
Exception.instance_method(:initialize).bind(o).call(val.delete('message'))
|
124
|
+
val.each_pair do |k,v|
|
125
|
+
o.instance_variable_set("@#{k}", v)
|
126
|
+
end
|
127
|
+
o
|
128
|
+
end
|
129
|
+
def to_yaml( opts = {} )
|
130
|
+
Syck::quick_emit( self, opts ) do |out|
|
131
|
+
out.map( taguri, to_yaml_style ) do |map|
|
132
|
+
map.add( 'message', message )
|
133
|
+
to_yaml_properties.each do |m|
|
134
|
+
map.add( m[1..-1], instance_variable_get( m ) )
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
class String
|
142
|
+
yaml_as "tag:ruby.yaml.org,2002:string"
|
143
|
+
yaml_as "tag:yaml.org,2002:binary"
|
144
|
+
yaml_as "tag:yaml.org,2002:str"
|
145
|
+
def is_complex_yaml?
|
146
|
+
to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
|
147
|
+
end
|
148
|
+
def is_binary_data?
|
149
|
+
self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty?
|
150
|
+
end
|
151
|
+
def String.yaml_new( klass, tag, val )
|
152
|
+
val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
|
153
|
+
val = { 'str' => val } if String === val
|
154
|
+
if Hash === val
|
155
|
+
s = klass.allocate
|
156
|
+
# Thank you, NaHi
|
157
|
+
String.instance_method(:initialize).
|
158
|
+
bind(s).
|
159
|
+
call( val.delete( 'str' ) )
|
160
|
+
val.each { |k,v| s.instance_variable_set( k, v ) }
|
161
|
+
s
|
162
|
+
else
|
163
|
+
raise Syck::TypeError, "Invalid String: " + val.inspect
|
164
|
+
end
|
165
|
+
end
|
166
|
+
def to_yaml( opts = {} )
|
167
|
+
Syck::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
|
168
|
+
if is_binary_data?
|
169
|
+
out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
|
170
|
+
elsif to_yaml_properties.empty?
|
171
|
+
out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
|
172
|
+
else
|
173
|
+
out.map( taguri, to_yaml_style ) do |map|
|
174
|
+
map.add( 'str', "#{self}" )
|
175
|
+
to_yaml_properties.each do |m|
|
176
|
+
map.add( m, instance_variable_get( m ) )
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
class Symbol
|
185
|
+
yaml_as "tag:ruby.yaml.org,2002:symbol"
|
186
|
+
yaml_as "tag:ruby.yaml.org,2002:sym"
|
187
|
+
def Symbol.yaml_new( klass, tag, val )
|
188
|
+
if String === val
|
189
|
+
val = Syck::load( val ) if val =~ /\A(["']).*\1\z/
|
190
|
+
val.intern
|
191
|
+
else
|
192
|
+
raise Syck::TypeError, "Invalid Symbol: " + val.inspect
|
193
|
+
end
|
194
|
+
end
|
195
|
+
def to_yaml( opts = {} )
|
196
|
+
Syck::quick_emit( nil, opts ) do |out|
|
197
|
+
out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
class Range
|
203
|
+
yaml_as "tag:ruby.yaml.org,2002:range"
|
204
|
+
def Range.yaml_new( klass, tag, val )
|
205
|
+
inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
|
206
|
+
opts = {}
|
207
|
+
if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
|
208
|
+
r1, rdots, r2 = $1, $2, $3
|
209
|
+
opts = {
|
210
|
+
'begin' => Syck.load( "--- #{r1}" ),
|
211
|
+
'end' => Syck.load( "--- #{r2}" ),
|
212
|
+
'excl' => rdots.length == 3
|
213
|
+
}
|
214
|
+
val = {}
|
215
|
+
elsif Hash === val
|
216
|
+
opts['begin'] = val.delete('begin')
|
217
|
+
opts['end'] = val.delete('end')
|
218
|
+
opts['excl'] = val.delete('excl')
|
219
|
+
end
|
220
|
+
if Hash === opts
|
221
|
+
r = Syck::object_maker( klass, {} )
|
222
|
+
# Thank you, NaHi
|
223
|
+
Range.instance_method(:initialize).
|
224
|
+
bind(r).
|
225
|
+
call( opts['begin'], opts['end'], opts['excl'] )
|
226
|
+
val.each { |k,v| r.instance_variable_set( k, v ) }
|
227
|
+
r
|
228
|
+
else
|
229
|
+
raise Syck::TypeError, "Invalid Range: " + val.inspect
|
230
|
+
end
|
231
|
+
end
|
232
|
+
def to_yaml( opts = {} )
|
233
|
+
Syck::quick_emit( self, opts ) do |out|
|
234
|
+
# if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
|
235
|
+
# self.end.is_complex_yaml? or self.end.respond_to? :to_str or
|
236
|
+
# not to_yaml_properties.empty?
|
237
|
+
out.map( taguri, to_yaml_style ) do |map|
|
238
|
+
map.add( 'begin', self.begin )
|
239
|
+
map.add( 'end', self.end )
|
240
|
+
map.add( 'excl', self.exclude_end? )
|
241
|
+
to_yaml_properties.each do |m|
|
242
|
+
map.add( m, instance_variable_get( m ) )
|
243
|
+
end
|
244
|
+
end
|
245
|
+
# else
|
246
|
+
# out.scalar( taguri ) do |sc|
|
247
|
+
# sc.embed( self.begin )
|
248
|
+
# sc.concat( self.exclude_end? ? "..." : ".." )
|
249
|
+
# sc.embed( self.end )
|
250
|
+
# end
|
251
|
+
# end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
class Regexp
|
257
|
+
yaml_as "tag:ruby.yaml.org,2002:regexp"
|
258
|
+
def Regexp.yaml_new( klass, tag, val )
|
259
|
+
if String === val and val =~ /^\/(.*)\/([mixn]*)$/
|
260
|
+
val = { 'regexp' => $1, 'mods' => $2 }
|
261
|
+
end
|
262
|
+
if Hash === val
|
263
|
+
mods = nil
|
264
|
+
unless val['mods'].to_s.empty?
|
265
|
+
mods = 0x00
|
266
|
+
mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
|
267
|
+
mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
|
268
|
+
mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
|
269
|
+
mods |= Regexp::NOENCODING if val['mods'].include?( 'n' )
|
270
|
+
end
|
271
|
+
val.delete( 'mods' )
|
272
|
+
r = Syck::object_maker( klass, {} )
|
273
|
+
Regexp.instance_method(:initialize).
|
274
|
+
bind(r).
|
275
|
+
call( val.delete( 'regexp' ), mods )
|
276
|
+
val.each { |k,v| r.instance_variable_set( k, v ) }
|
277
|
+
r
|
278
|
+
else
|
279
|
+
raise Syck::TypeError, "Invalid Regular expression: " + val.inspect
|
280
|
+
end
|
281
|
+
end
|
282
|
+
def to_yaml( opts = {} )
|
283
|
+
Syck::quick_emit( nil, opts ) do |out|
|
284
|
+
if to_yaml_properties.empty?
|
285
|
+
out.scalar( taguri, self.inspect, :plain )
|
286
|
+
else
|
287
|
+
out.map( taguri, to_yaml_style ) do |map|
|
288
|
+
src = self.inspect
|
289
|
+
if src =~ /\A\/(.*)\/([a-z]*)\Z/
|
290
|
+
map.add( 'regexp', $1 )
|
291
|
+
map.add( 'mods', $2 )
|
292
|
+
else
|
293
|
+
raise Syck::TypeError, "Invalid Regular expression: " + src
|
294
|
+
end
|
295
|
+
to_yaml_properties.each do |m|
|
296
|
+
map.add( m, instance_variable_get( m ) )
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
class Time
|
305
|
+
yaml_as "tag:ruby.yaml.org,2002:time"
|
306
|
+
yaml_as "tag:yaml.org,2002:timestamp"
|
307
|
+
def Time.yaml_new( klass, tag, val )
|
308
|
+
if Hash === val
|
309
|
+
t = val.delete( 'at' )
|
310
|
+
val.each { |k,v| t.instance_variable_set( k, v ) }
|
311
|
+
t
|
312
|
+
else
|
313
|
+
raise Syck::TypeError, "Invalid Time: " + val.inspect
|
314
|
+
end
|
315
|
+
end
|
316
|
+
def to_yaml( opts = {} )
|
317
|
+
Syck::quick_emit( self, opts ) do |out|
|
318
|
+
tz = "Z"
|
319
|
+
# from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
|
320
|
+
unless self.utc?
|
321
|
+
utc_same_instant = self.dup.utc
|
322
|
+
utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
|
323
|
+
difference_to_utc = utc_same_writing - utc_same_instant
|
324
|
+
if (difference_to_utc < 0)
|
325
|
+
difference_sign = '-'
|
326
|
+
absolute_difference = -difference_to_utc
|
327
|
+
else
|
328
|
+
difference_sign = '+'
|
329
|
+
absolute_difference = difference_to_utc
|
330
|
+
end
|
331
|
+
difference_minutes = (absolute_difference/60).round
|
332
|
+
tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
|
333
|
+
end
|
334
|
+
standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
|
335
|
+
standard += ".%06d" % [usec] if usec.nonzero?
|
336
|
+
standard += " %s" % [tz]
|
337
|
+
if to_yaml_properties.empty?
|
338
|
+
out.scalar( taguri, standard, :plain )
|
339
|
+
else
|
340
|
+
out.map( taguri, to_yaml_style ) do |map|
|
341
|
+
map.add( 'at', standard )
|
342
|
+
to_yaml_properties.each do |m|
|
343
|
+
map.add( m, instance_variable_get( m ) )
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
class Date
|
352
|
+
yaml_as "tag:yaml.org,2002:timestamp#ymd"
|
353
|
+
def to_yaml( opts = {} )
|
354
|
+
Syck::quick_emit( self, opts ) do |out|
|
355
|
+
out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
class Integer
|
361
|
+
yaml_as "tag:yaml.org,2002:int"
|
362
|
+
def to_yaml( opts = {} )
|
363
|
+
Syck::quick_emit( nil, opts ) do |out|
|
364
|
+
out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
class Float
|
370
|
+
yaml_as "tag:yaml.org,2002:float"
|
371
|
+
def to_yaml( opts = {} )
|
372
|
+
Syck::quick_emit( nil, opts ) do |out|
|
373
|
+
str = self.to_s
|
374
|
+
if str == "Infinity"
|
375
|
+
str = ".Inf"
|
376
|
+
elsif str == "-Infinity"
|
377
|
+
str = "-.Inf"
|
378
|
+
elsif str == "NaN"
|
379
|
+
str = ".NaN"
|
380
|
+
end
|
381
|
+
out.scalar( "tag:yaml.org,2002:float", str, :plain )
|
382
|
+
end
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
class Rational
|
387
|
+
yaml_as "tag:ruby.yaml.org,2002:object:Rational"
|
388
|
+
def Rational.yaml_new( klass, tag, val )
|
389
|
+
if val.is_a? String
|
390
|
+
Rational( val )
|
391
|
+
else
|
392
|
+
Rational( val['numerator'], val['denominator'] )
|
393
|
+
end
|
394
|
+
end
|
395
|
+
def to_yaml( opts = {} )
|
396
|
+
Syck::quick_emit( self, opts ) do |out|
|
397
|
+
out.map( taguri, nil ) do |map|
|
398
|
+
map.add( 'denominator', denominator )
|
399
|
+
map.add( 'numerator', numerator )
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
class Complex
|
406
|
+
yaml_as "tag:ruby.yaml.org,2002:object:Complex"
|
407
|
+
def Complex.yaml_new( klass, tag, val )
|
408
|
+
if val.is_a? String
|
409
|
+
Complex( val )
|
410
|
+
else
|
411
|
+
Complex( val['real'], val['image'] )
|
412
|
+
end
|
413
|
+
end
|
414
|
+
def to_yaml( opts = {} )
|
415
|
+
Syck::quick_emit( self, opts ) do |out|
|
416
|
+
out.map( taguri, nil ) do |map|
|
417
|
+
map.add( 'image', imaginary )
|
418
|
+
map.add( 'real', real )
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
class TrueClass
|
425
|
+
yaml_as "tag:yaml.org,2002:bool#yes"
|
426
|
+
def to_yaml( opts = {} )
|
427
|
+
Syck::quick_emit( nil, opts ) do |out|
|
428
|
+
out.scalar( taguri, "true", :plain )
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
class FalseClass
|
434
|
+
yaml_as "tag:yaml.org,2002:bool#no"
|
435
|
+
def to_yaml( opts = {} )
|
436
|
+
Syck::quick_emit( nil, opts ) do |out|
|
437
|
+
out.scalar( taguri, "false", :plain )
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
class NilClass
|
443
|
+
yaml_as "tag:yaml.org,2002:null"
|
444
|
+
def to_yaml( opts = {} )
|
445
|
+
Syck::quick_emit( nil, opts ) do |out|
|
446
|
+
out.scalar( taguri, "", :plain )
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|