diff options
author | Rick Olson <technoweenie@gmail.com> | 2007-09-24 17:41:55 +0000 |
---|---|---|
committer | Rick Olson <technoweenie@gmail.com> | 2007-09-24 17:41:55 +0000 |
commit | 2a60093fa35312e83aeaa3185ea0fc20f3ee50be (patch) | |
tree | f6070ca6ae02060b2892807f1cf171a240aa92de | |
parent | 911ea2f26f0a8d240b8a76a41d7a4ce978c72b12 (diff) | |
download | rails-2a60093fa35312e83aeaa3185ea0fc20f3ee50be.tar.gz rails-2a60093fa35312e83aeaa3185ea0fc20f3ee50be.tar.bz2 rails-2a60093fa35312e83aeaa3185ea0fc20f3ee50be.zip |
Decode json strings as Dates/Times if they're using a YAML-compatible format. Closes #9614 [Rick]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@7613 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/json/decoding.rb | 23 | ||||
-rw-r--r-- | activesupport/test/json/decoding_test.rb | 12 |
3 files changed, 29 insertions, 8 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 7187d6060c..220617fefd 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Decode json strings as Dates/Times if they're using a YAML-compatible format. Closes #9614 [Rick] + * Fixed cache_page to use the request url instead of the routing options when picking a save path #8614 [josh] * Object.subclasses_of includes anonymous subclasses. [Jeremy Kemper] diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb index 08446d3a83..b6370ddb0e 100644 --- a/activesupport/lib/active_support/json/decoding.rb +++ b/activesupport/lib/active_support/json/decoding.rb @@ -15,17 +15,26 @@ module ActiveSupport end protected - + # matches YAML-formatted dates + DATE_REGEX = /^\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?$/ + # Ensure that ":" and "," are always followed by a space def convert_json_to_yaml(json) #:nodoc: - scanner, quoting, marks = StringScanner.new(json), false, [] - + scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, [] while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/) case char = scanner[1] when '"', "'" if !quoting quoting = char + pos = scanner.pos elsif quoting == char + if json[pos..scanner.pos-2] =~ DATE_REGEX + # found a date, track the exact positions of the quotes so we can remove them later. + # oh, and increment them for each current mark, each one is an extra padded space that bumps + # the position in the final yaml output + total_marks = marks.size + times << pos+total_marks << scanner.pos+total_marks + end quoting = false end when ":","," @@ -37,9 +46,13 @@ module ActiveSupport json else ranges = ([0] + marks.map(&:succ)).zip(marks + [json.length]) - ranges.map { |(left, right)| json[left..right] }.join(" ") + output = ranges.collect! { |(left, right)| json[left..right] }.join(" ") + times.each do |pos| + output[pos-1] = ' ' + end + output end - end + end end end end diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb index 01796d5e99..f0b0da32c8 100644 --- a/activesupport/test/json/decoding_test.rb +++ b/activesupport/test/json/decoding_test.rb @@ -8,8 +8,14 @@ class TestJSONDecoding < Test::Unit::TestCase %({"returnTo":{"/categories":1}}) => {"returnTo" => {"/categories" => 1}}, %({"returnTo":[1,"a"]}) => {"returnTo" => [1, "a"]}, %({"returnTo":[1,"\\"a\\",", "b"]}) => {"returnTo" => [1, "\"a\",", "b"]}, - %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"}, - %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"}, + %({a: "'", "b": "5,000"}) => {"a" => "'", "b" => "5,000"}, + %({a: "a's, b's and c's", "b": "5,000"}) => {"a" => "a's, b's and c's", "b" => "5,000"}, + %({a: "2007-01-01"}) => {'a' => Date.new(2007, 1, 1)}, + %({a: "2007-01-01 01:12:34 Z"}) => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)}, + # no time zone + %({a: "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"}, + # needs to be *exact* + %({a: " 2007-01-01 01:12:34 Z "}) => {'a' => " 2007-01-01 01:12:34 Z "}, %([]) => [], %({}) => {}, %(1) => 1, @@ -31,4 +37,4 @@ class TestJSONDecoding < Test::Unit::TestCase def test_failed_json_decoding assert_raises(ActiveSupport::JSON::ParseError) { ActiveSupport::JSON.decode(%({: 1})) } end -end +end
\ No newline at end of file |