aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2007-04-21 14:12:05 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2007-04-21 14:12:05 +0000
commit178880ef7c4953470453c258abccf99b98c92bb9 (patch)
treee8b6ba2b3a8ce903b9ccdf37d113d69136efe237 /activesupport/lib/active_support
parenteb7a3045e3035d7de35a43297a4f36255e4f178d (diff)
downloadrails-178880ef7c4953470453c258abccf99b98c92bb9.tar.gz
rails-178880ef7c4953470453c258abccf99b98c92bb9.tar.bz2
rails-178880ef7c4953470453c258abccf99b98c92bb9.zip
Use XSD-compatible type names for Hash#to_xml and make the converters extendable #8047 [Tim Pope]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@6546 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb41
1 files changed, 30 insertions, 11 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 4e076dce6e..4fb3cbe4d3 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -1,6 +1,7 @@
require 'date'
require 'xml_simple'
require 'cgi'
+require 'base64'
# Extensions needed for Hash#to_query
class Object
@@ -26,21 +27,40 @@ module ActiveSupport #:nodoc:
XML_TYPE_NAMES = {
"Fixnum" => "integer",
"Bignum" => "integer",
- "BigDecimal" => "numeric",
+ "BigDecimal" => "decimal",
"Float" => "float",
"Date" => "date",
"DateTime" => "datetime",
"Time" => "datetime",
"TrueClass" => "boolean",
"FalseClass" => "boolean"
- } unless defined? XML_TYPE_NAMES
+ } unless defined?(XML_TYPE_NAMES)
XML_FORMATTING = {
"date" => Proc.new { |date| date.to_s(:db) },
"datetime" => Proc.new { |time| time.xmlschema },
"binary" => Proc.new { |binary| Base64.encode64(binary) },
"yaml" => Proc.new { |yaml| yaml.to_yaml }
- } unless defined? XML_FORMATTING
+ } unless defined?(XML_FORMATTING)
+
+ unless defined?(XML_PARSING)
+ XML_PARSING = {
+ "date" => Proc.new { |date| ::Date.parse(date) },
+ "datetime" => Proc.new { |time| ::Time.parse(time).utc },
+ "integer" => Proc.new { |integer| integer.to_i },
+ "float" => Proc.new { |float| float.to_f },
+ "decimal" => Proc.new { |number| BigDecimal(number) },
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
+ "string" => Proc.new { |string| string.to_s },
+ "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
+ "base64Binary" => Proc.new { |bin| Base64.decode64(bin) }
+ }
+
+ XML_PARSING.update(
+ "double" => XML_PARSING["float"],
+ "dateTime" => XML_PARSING["datetime"]
+ )
+ end
def self.included(klass)
klass.extend(ClassMethods)
@@ -127,14 +147,13 @@ module ActiveSupport #:nodoc:
when "Hash"
if value.has_key?("__content__")
content = translate_xml_entities(value["__content__"])
- case value["type"]
- when "integer" then content.to_i
- when "boolean" then content.strip == "true"
- when "datetime" then ::Time.parse(content).utc
- when "date" then ::Date.parse(content)
- when "yaml" then YAML::load(content) rescue content
- else content
+ if XML_PARSING[value["type"]]
+ XML_PARSING[value["type"]].call(content)
+ else
+ content
end
+ elsif value['type'] == 'string' && value['nil'] != 'true'
+ ""
else
(value.blank? || value['type'] || value['nil'] == 'true') ? nil : value.inject({}) do |h,(k,v)|
h[k] = typecast_xml_value(v)
@@ -180,4 +199,4 @@ module ActiveSupport #:nodoc:
end
end
end
-end
+end \ No newline at end of file