Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 7613

Show
Ignore:
Timestamp:
09/24/07 17:41:55 (1 year ago)
Author:
rick
Message:

Decode json strings as Dates/Times if they're using a YAML-compatible format. Closes #9614 [Rick]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activesupport/CHANGELOG

    r7602 r7613  
    11*SVN* 
     2 
     3* Decode json strings as Dates/Times if they're using a YAML-compatible format.  Closes #9614 [Rick] 
    24 
    35* Fixed cache_page to use the request url instead of the routing options when picking a save path #8614 [josh] 
  • trunk/activesupport/lib/active_support/json/decoding.rb

    r7506 r7613  
    1616       
    1717      protected 
    18          
     18        # matches YAML-formatted dates 
     19        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})?)?$/ 
     20 
    1921        # Ensure that ":" and "," are always followed by a space 
    2022        def convert_json_to_yaml(json) #:nodoc: 
    21           scanner, quoting, marks = StringScanner.new(json), false, [] 
    22  
     23          scanner, quoting, marks, pos, times = StringScanner.new(json), false, [], nil, [] 
    2324          while scanner.scan_until(/(\\['"]|['":,\\]|\\.)/) 
    2425            case char = scanner[1] 
     
    2627              if !quoting 
    2728                quoting = char 
     29                pos = scanner.pos 
    2830              elsif quoting == char 
     31                if json[pos..scanner.pos-2] =~ DATE_REGEX 
     32                  # found a date, track the exact positions of the quotes so we can remove them later. 
     33                  # oh, and increment them for each current mark, each one is an extra padded space that bumps 
     34                  # the position in the final yaml output 
     35                  total_marks = marks.size 
     36                  times << pos+total_marks << scanner.pos+total_marks 
     37                end 
    2938                quoting = false 
    3039              end 
     
    3847          else 
    3948            ranges = ([0] + marks.map(&:succ)).zip(marks + [json.length]) 
    40             ranges.map { |(left, right)| json[left..right] }.join(" ") 
     49            output = ranges.collect! { |(left, right)| json[left..right] }.join(" ") 
     50            times.each do |pos| 
     51              output[pos-1] = ' ' 
     52            end 
     53            output 
    4154          end 
    42         end   
     55        end 
    4356    end 
    4457  end 
  • trunk/activesupport/test/json/decoding_test.rb

    r7506 r7613  
    99    %({"returnTo":[1,"a"]})                    => {"returnTo" => [1, "a"]}, 
    1010    %({"returnTo":[1,"\\"a\\",", "b"]})        => {"returnTo" => [1, "\"a\",", "b"]}, 
    11     %({a: "'", "b": "5,000"})     => {"a" => "'", "b" => "5,000"}, 
    12     %({a: "a's, b's and c's", "b": "5,000"})     => {"a" => "a's, b's and c's", "b" => "5,000"}, 
     11    %({a: "'", "b": "5,000"})                  => {"a" => "'", "b" => "5,000"}, 
     12    %({a: "a's, b's and c's", "b": "5,000"})   => {"a" => "a's, b's and c's", "b" => "5,000"}, 
     13    %({a: "2007-01-01"})                       => {'a' => Date.new(2007, 1, 1)},  
     14    %({a: "2007-01-01 01:12:34 Z"})            => {'a' => Time.utc(2007, 1, 1, 1, 12, 34)},  
     15    # no time zone 
     16    %({a: "2007-01-01 01:12:34"})              => {'a' => "2007-01-01 01:12:34"},  
     17    # needs to be *exact* 
     18    %({a: " 2007-01-01 01:12:34 Z "})          => {'a' => " 2007-01-01 01:12:34 Z "},  
    1319    %([])    => [], 
    1420    %({})    => {},