summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/psych/nodes/node.rb1
-rw-r--r--lib/psych/scalar_scanner.rb10
-rw-r--r--lib/psych/visitors/to_ruby.rb43
-rw-r--r--lib/psych/visitors/visitor.rb24
-rw-r--r--test/test_scalar_scanner.rb6
5 files changed, 46 insertions, 38 deletions
diff --git a/lib/psych/nodes/node.rb b/lib/psych/nodes/node.rb
index 6aaba15..7b5269e 100644
--- a/lib/psych/nodes/node.rb
+++ b/lib/psych/nodes/node.rb
@@ -9,6 +9,7 @@ module Psych
include Psych::Visitable
attr_reader :children
+ attr_reader :tag
def initialize
@children = []
diff --git a/lib/psych/scalar_scanner.rb b/lib/psych/scalar_scanner.rb
index 6a18fa1..3afb7c6 100644
--- a/lib/psych/scalar_scanner.rb
+++ b/lib/psych/scalar_scanner.rb
@@ -16,8 +16,11 @@ module Psych
case @string
when /^[A-Za-z~]/
+ return [:SCALAR, @string] if @string.length > 5
case @string
- when /^(null|~)$/i
+ when /^[^ytonf~]/i
+ [:SCALAR, @string]
+ when '~', /^null$/i
[:NULL, nil]
when /^(yes|true|on)$/i
[:BOOLEAN, true]
@@ -29,14 +32,15 @@ module Psych
when TIME
[:TIME, @string]
when /^\d{4}-\d{1,2}-\d{1,2}$/
- [:DATE, @string]
+ require 'date'
+ [:DATE, Date.strptime(@string, '%Y-%m-%d')]
when /^\.inf$/i
[:POSITIVE_INFINITY, 1 / 0.0]
when /^-\.inf$/i
[:NEGATIVE_INFINITY, -1 / 0.0]
when /^\.nan$/i
[:NAN, 0.0 / 0.0]
- when /^:.+/
+ when /^:./
if @string =~ /^:(["'])(.*)\1/
[:SYMBOL, $2.sub(/^:/, '').to_sym]
else
diff --git a/lib/psych/visitors/to_ruby.rb b/lib/psych/visitors/to_ruby.rb
index f9fd2f9..fa13d2e 100644
--- a/lib/psych/visitors/to_ruby.rb
+++ b/lib/psych/visitors/to_ruby.rb
@@ -13,14 +13,14 @@ module Psych
def accept target
result = super
return result if Psych.domain_types.empty?
+ return result unless target.tag
- if target.respond_to?(:tag) && target.tag
- short_name = target.tag.sub(/^!/, '').split('/', 2).last
- if Psych.domain_types.key? short_name
- url, block = Psych.domain_types[short_name]
- return block.call "http://#{url}:#{short_name}", result
- end
+ short_name = target.tag.sub(/^!/, '').split('/', 2).last
+ if Psych.domain_types.key? short_name
+ url, block = Psych.domain_types[short_name]
+ return block.call "http://#{url}:#{short_name}", result
end
+
result
end
@@ -201,31 +201,22 @@ module Psych
end
def resolve_unknown o
- token = ScalarScanner.new(o.value).tokenize
-
- case token.first
- when :DATE
- require 'date'
- Date.strptime token.last, '%Y-%m-%d'
- when :TIME
- lexeme = token.last
+ type, lexeme = ScalarScanner.new(o.value).tokenize
+ return lexeme unless :TIME == type
- date, time = *(lexeme.split(/[ tT]/, 2))
- (yy, m, dd) = date.split('-').map { |x| x.to_i }
- md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/)
+ date, time = *(lexeme.split(/[ tT]/, 2))
+ (yy, m, dd) = date.split('-').map { |x| x.to_i }
+ md = time.match(/(\d+:\d+:\d+)(\.\d*)?\s*(Z|[-+]\d+(:\d\d)?)?/)
- (hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
- us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000
+ (hh, mm, ss) = md[1].split(':').map { |x| x.to_i }
+ us = (md[2] ? Rational(md[2].sub(/^\./, '0.')) : 0) * 1000000
- time = Time.utc(yy, m, dd, hh, mm, ss, us)
+ time = Time.utc(yy, m, dd, hh, mm, ss, us)
- return time if 'Z' == md[3]
+ return time if 'Z' == md[3]
- tz = md[3] ? Integer(md[3].split(':').first) : 0
- Time.at((time - (tz * 3600)).to_i, us)
- else
- token.last
- end
+ tz = md[3] ? Integer(md[3].split(':').first) : 0
+ Time.at((time - (tz * 3600)).to_i, us)
end
end
end
diff --git a/lib/psych/visitors/visitor.rb b/lib/psych/visitors/visitor.rb
index 56be391..da0bf4c 100644
--- a/lib/psych/visitors/visitor.rb
+++ b/lib/psych/visitors/visitor.rb
@@ -1,15 +1,23 @@
module Psych
module Visitors
class Visitor
- YAML_NODE_DISPATCH_TABLE = Hash[
- *Nodes.constants.map { |k|
- k = Nodes.const_get k
- [k, :"visit_#{k.name.split('::').join('_')}"]
- }.flatten
- ]
-
def accept target
- send(YAML_NODE_DISPATCH_TABLE[target.class], target)
+ case target
+ when Psych::Nodes::Scalar
+ visit_Psych_Nodes_Scalar target
+ when Psych::Nodes::Mapping
+ visit_Psych_Nodes_Mapping target
+ when Psych::Nodes::Sequence
+ visit_Psych_Nodes_Sequence target
+ when Psych::Nodes::Document
+ visit_Psych_Nodes_Document target
+ when Psych::Nodes::Stream
+ visit_Psych_Nodes_Stream target
+ when Psych::Nodes::Alias
+ visit_Psych_Nodes_Alias target
+ else
+ raise "Can't handle #{target}"
+ end
end
end
end
diff --git a/test/test_scalar_scanner.rb b/test/test_scalar_scanner.rb
index 31e3041..eccb2b4 100644
--- a/test/test_scalar_scanner.rb
+++ b/test/test_scalar_scanner.rb
@@ -16,7 +16,11 @@ class TestScalarScanner < MiniTest::Unit::TestCase
def test_scan_date
date = '1980-12-16'
ss = Psych::ScalarScanner.new date
- assert_equal [:DATE, date], ss.tokenize
+ type, token = ss.tokenize
+ assert_equal :DATE, type
+ assert_equal 1980, token.year
+ assert_equal 12, token.month
+ assert_equal 16, token.day
end
def test_scan_inf