From 2a60093fa35312e83aeaa3185ea0fc20f3ee50be Mon Sep 17 00:00:00 2001 From: Rick Olson Date: Mon, 24 Sep 2007 17:41:55 +0000 Subject: 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 --- activesupport/lib/active_support/json/decoding.rb | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'activesupport/lib/active_support') 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 -- cgit v1.2.3