rackful 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/example/config.ru +11 -10
- data/lib/rackful.rb +9 -5
- data/lib/rackful/global.rb +12 -0
- data/lib/rackful/httpstatus.rb +50 -51
- data/lib/rackful/middleware.rb +5 -0
- data/lib/rackful/middleware/headerspoofing.rb +7 -1
- data/lib/rackful/middleware/methodoverride.rb +8 -2
- data/lib/rackful/parser.rb +80 -101
- data/lib/rackful/request.rb +100 -129
- data/lib/rackful/resource.rb +263 -207
- data/lib/rackful/serializer.rb +46 -17
- data/lib/rackful/server.rb +25 -33
- data/lib/rackful/uri.rb +8 -0
- data/rackful.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3ca6f8649b19811edf97934421a559a7737c0e4
|
4
|
+
data.tar.gz: 7ca6cbcbd870d257c2e05de94ff612b43802bbf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebe348706302e4f09e1cc9670135f87ab8092b397514fa049164cd0e6a9880d3418c1c1f456d9e8a54aac9f650b297bc0ff76a8ea10275eeafd2d28e4a49315a
|
7
|
+
data.tar.gz: dc046d625255efb54558810c9069ee89856963fac75b1672b7b3877dc5ff4647ffdd3937d086d509479b91ccecffc6e67111582021458f88bd02d1e401a39d31
|
data/example/config.ru
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
# Load core functionality:
|
2
2
|
require 'rackful'
|
3
3
|
|
4
|
+
|
4
5
|
# Load extra middlewares: ({Rackful::MethodOverride}, {Rackful::HeaderSpoofing})
|
5
6
|
require 'rackful/middleware'
|
6
|
-
|
7
7
|
require 'digest/md5'
|
8
8
|
|
9
|
+
|
9
10
|
# The class of the object we're going to serve:
|
10
|
-
class
|
11
|
-
|
11
|
+
class MyResource
|
12
|
+
include Rackful::Resource
|
13
|
+
attr_accessor :to_rackful
|
14
|
+
|
12
15
|
def initialize
|
13
|
-
|
16
|
+
self.uri = '/hello_world'
|
14
17
|
@to_rackful = {
|
15
18
|
:a => 'Hello',
|
16
19
|
:b => Time.now,
|
17
|
-
:c => URI('http://www.example.com/some/path')
|
18
|
-
|
19
|
-
def do_PUT request, response
|
20
|
-
@to_rackful = self.parser(request).parse
|
20
|
+
:c => URI('http://www.example.com/some/path')
|
21
|
+
}
|
21
22
|
end
|
23
|
+
|
22
24
|
def get_etag
|
23
25
|
'"' + Digest::MD5.new.update(to_rackful.inspect).to_s + '"'
|
24
26
|
end
|
@@ -27,12 +29,11 @@ class Root < Rackful::Resource
|
|
27
29
|
add_parser Rackful::Parser::XHTML
|
28
30
|
add_parser Rackful::Parser::JSON
|
29
31
|
end
|
30
|
-
$root_resource = nil
|
31
32
|
|
32
33
|
use Rack::Reloader
|
33
34
|
use Rackful::MethodOverride
|
34
35
|
use Rackful::HeaderSpoofing
|
35
36
|
|
36
37
|
run Rackful::Server.new { |uri|
|
37
|
-
$root_resource ||=
|
38
|
+
$root_resource ||= MyResource.new
|
38
39
|
}
|
data/lib/rackful.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# External requirements:
|
2
4
|
require 'nokogiri'
|
3
5
|
require 'rack'
|
4
6
|
require 'rack/utils'
|
@@ -6,10 +8,12 @@ require 'base64'
|
|
6
8
|
require 'time'
|
7
9
|
require 'json'
|
8
10
|
|
9
|
-
|
10
|
-
require 'rackful/
|
11
|
-
require 'rackful/
|
11
|
+
# Internal “core” files, in alphabetic order:
|
12
|
+
require 'rackful/global.rb'
|
13
|
+
require 'rackful/httpstatus.rb'
|
12
14
|
require 'rackful/parser.rb'
|
15
|
+
require 'rackful/request.rb'
|
13
16
|
require 'rackful/resource.rb'
|
14
|
-
require 'rackful/
|
17
|
+
require 'rackful/serializer.rb'
|
15
18
|
require 'rackful/server.rb'
|
19
|
+
require 'rackful/uri.rb'
|
data/lib/rackful/httpstatus.rb
CHANGED
@@ -1,63 +1,58 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
# Required for parsing:
|
4
|
+
require 'rackful/global.rb'
|
3
5
|
require 'rackful/resource.rb'
|
4
6
|
require 'rackful/serializer.rb'
|
5
7
|
|
8
|
+
# Required for running:
|
6
9
|
|
7
10
|
module Rackful
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
# Groups together class {HTTPStatus} and its many subclasses into one namespace.
|
13
|
+
#
|
14
|
+
# For code brevity and legibility, this module is included in {Rackful},
|
15
|
+
# {Resource}, {Serializer}, and {Parser}. So class
|
16
|
+
# {HTTP404NotFound Rackful::StatusCodes::HTTP404NotFound}
|
17
|
+
# can also be addressed as {HTTP404NotFound} in any of those contexts.
|
18
|
+
module StatusCodes
|
14
19
|
|
20
|
+
# Exception which represents an HTTP Status response.
|
21
|
+
# @abstract
|
22
|
+
class HTTPStatus < RuntimeError
|
15
23
|
|
16
|
-
|
17
|
-
|
24
|
+
include Resource
|
25
|
+
|
26
|
+
class XHTML < Serializer::XHTML
|
18
27
|
|
19
28
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
retval
|
29
|
+
def header
|
30
|
+
retval = super
|
31
|
+
retval += "<h1>HTTP/1.1 #{Rack::Utils.escape_html(resource.title)}</h1>\n"
|
32
|
+
unless resource.message.empty?
|
33
|
+
retval += "<div id=\"rackful-description\">#{resource.message}</div>\n"
|
27
34
|
end
|
35
|
+
retval
|
36
|
+
end
|
28
37
|
|
29
38
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end # class Rackful::HTTPStatus::XHTML
|
34
|
-
|
35
|
-
|
36
|
-
add_serializer XHTML, 1.0
|
37
|
-
|
38
|
-
extend Forwardable
|
39
|
-
def_delegators :@http_status_object, :headers, :to_rackful, :title, :message
|
40
|
-
|
39
|
+
def headers; self.resource.headers; end
|
41
40
|
|
42
|
-
def initialize(uri, http_status_object)
|
43
|
-
super(uri)
|
44
|
-
@http_status_object = http_status_object
|
45
|
-
end
|
46
41
|
|
42
|
+
end # class Rackful::StatusCodes::HTTPStatus::XHTML
|
47
43
|
|
48
|
-
end # class Rackful::HTTPStatus::Resource
|
49
44
|
|
45
|
+
add_serializer XHTML, 1.0
|
46
|
+
add_serializer Serializer::JSON, 0.5
|
50
47
|
|
51
48
|
attr_reader :status, :headers, :to_rackful
|
52
49
|
|
53
50
|
|
54
|
-
|
55
|
-
@param
|
56
|
-
@param
|
57
|
-
|
58
|
-
|
59
|
-
* **Strings** indexed by **Strings** are returned as response headers.
|
60
|
-
=end
|
51
|
+
# @param status [Symbol, Integer] e.g. `404` or `:not_found`
|
52
|
+
# @param message [String] XHTML
|
53
|
+
# @param info [ { Symbol => Object, String => String } ]
|
54
|
+
# * **Objects** indexed by **Symbols** are returned in the response body.
|
55
|
+
# * **Strings** indexed by **Strings** are returned as response headers.
|
61
56
|
def initialize status, message = nil, info = {}
|
62
57
|
@status = Rack::Utils.status_code status
|
63
58
|
raise "Wrong status: #{status}" if 0 === @status
|
@@ -86,24 +81,20 @@ class HTTPStatus < RuntimeError
|
|
86
81
|
end
|
87
82
|
super message
|
88
83
|
end
|
89
|
-
|
90
|
-
def serializer request
|
91
|
-
Resource.new( request.url, self ).serializer( request )
|
92
|
-
end
|
93
84
|
|
85
|
+
|
86
|
+
# @api private
|
94
87
|
def title
|
95
88
|
"#{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}"
|
96
89
|
end
|
97
90
|
|
98
91
|
|
99
92
|
|
100
|
-
end # class Rackful::HTTPStatus
|
93
|
+
end # class Rackful::StatusCodes::HTTPStatus
|
101
94
|
|
102
95
|
|
103
|
-
|
104
|
-
|
105
|
-
no message at all.
|
106
|
-
=end
|
96
|
+
# @abstract Base class for HTTP status codes with only a simple text message, or
|
97
|
+
# no message at all.
|
107
98
|
class HTTPSimpleStatus < HTTPStatus
|
108
99
|
|
109
100
|
def initialize message = nil
|
@@ -117,9 +108,12 @@ end
|
|
117
108
|
|
118
109
|
class HTTP201Created < HTTPStatus
|
119
110
|
|
111
|
+
# @param locations [URI::Generic, String, Array<URI::Generic, String>]
|
120
112
|
def initialize locations
|
121
113
|
locations = [ locations ] unless locations.kind_of? Array
|
122
|
-
locations = locations.collect
|
114
|
+
locations = locations.collect do |location|
|
115
|
+
location.kind_of?( URI::Generic ) ? location : URI(location).normalize
|
116
|
+
end
|
123
117
|
if locations.size > 1
|
124
118
|
super( 201, 'New resources were created:', :locations => locations )
|
125
119
|
else
|
@@ -136,9 +130,10 @@ end
|
|
136
130
|
|
137
131
|
class HTTP202Accepted < HTTPStatus
|
138
132
|
|
133
|
+
# @param location [URI::Generic, String]
|
139
134
|
def initialize location = nil
|
140
135
|
if location
|
141
|
-
location = URI(location)
|
136
|
+
location = location.kind_of?( URI::Generic ) ? location : URI(location).normalize
|
142
137
|
super(
|
143
138
|
202, "The request body you sent has been accepted for processing.",
|
144
139
|
:"Job status location:" => location, 'Location' => location
|
@@ -153,8 +148,9 @@ end
|
|
153
148
|
|
154
149
|
class HTTP301MovedPermanently < HTTPStatus
|
155
150
|
|
151
|
+
# @param location [URI::Generic, String]
|
156
152
|
def initialize location
|
157
|
-
location = URI(location)
|
153
|
+
location = location.kind_of?( URI::Generic ) ? location : URI(location).normalize
|
158
154
|
super( 301, '', :'New location:' => location, 'Location' => location )
|
159
155
|
end
|
160
156
|
|
@@ -163,8 +159,9 @@ end
|
|
163
159
|
|
164
160
|
class HTTP303SeeOther < HTTPStatus
|
165
161
|
|
162
|
+
# @param location [URI::Generic, String]
|
166
163
|
def initialize location
|
167
|
-
location = URI(location)
|
164
|
+
location = location.kind_of?( URI::Generic ) ? location : URI(location).normalize
|
168
165
|
super( 303, '', :'See:' => location, 'Location' => location )
|
169
166
|
end
|
170
167
|
|
@@ -182,8 +179,9 @@ end
|
|
182
179
|
|
183
180
|
class HTTP307TemporaryRedirect < HTTPStatus
|
184
181
|
|
182
|
+
# @param location [URI::Generic, String]
|
185
183
|
def initialize location
|
186
|
-
location = URI(location)
|
184
|
+
location = location.kind_of?( URI::Generic ) ? location : URI(location).normalize
|
187
185
|
super( 301, '', :'Current location:' => location, 'Location' => location )
|
188
186
|
end
|
189
187
|
|
@@ -247,4 +245,5 @@ class HTTP501NotImplemented < HTTPSimpleStatus; end
|
|
247
245
|
|
248
246
|
class HTTP503ServiceUnavailable < HTTPSimpleStatus; end
|
249
247
|
|
248
|
+
end # module Rackful::StatusCodes
|
250
249
|
end # module Rackful
|
data/lib/rackful/middleware.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
# Required for parsing:
|
4
|
+
|
5
|
+
# This requirement is only made explicit in source files that aren’t
|
6
|
+
# included in the rackful “core”.
|
3
7
|
require 'rackful'
|
4
8
|
|
5
9
|
# Required for running:
|
6
10
|
|
11
|
+
module Rackful
|
7
12
|
|
8
13
|
# Rack middleware that provides header spoofing.
|
9
14
|
#
|
@@ -18,7 +23,7 @@ require 'rackful'
|
|
18
23
|
# @example Using this middleware
|
19
24
|
# require 'rackful/middleware/header_spoofing'
|
20
25
|
# use Rackful::HeaderSpoofing
|
21
|
-
class
|
26
|
+
class HeaderSpoofing
|
22
27
|
|
23
28
|
def initialize app
|
24
29
|
@app = app
|
@@ -47,3 +52,4 @@ def call env
|
|
47
52
|
end
|
48
53
|
|
49
54
|
end # Rackful::HeaderSpoofing
|
55
|
+
end # module Rackful
|
@@ -1,9 +1,14 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
|
2
3
|
# Required for parsing:
|
4
|
+
|
5
|
+
# This requirement is only made explicit in source files that aren’t
|
6
|
+
# included in the rackful “core”.
|
3
7
|
require 'rackful'
|
4
8
|
|
5
9
|
# Required for running:
|
6
|
-
|
10
|
+
|
11
|
+
module Rackful
|
7
12
|
|
8
13
|
|
9
14
|
# Middleware that provides method spoofing, like {Rack::MethodOverride}.
|
@@ -47,7 +52,7 @@ require 'set'
|
|
47
52
|
# @example Using this middleware
|
48
53
|
# require 'rackful/middleware/method_override'
|
49
54
|
# use Rackful::MethodOverride
|
50
|
-
class
|
55
|
+
class MethodOverride
|
51
56
|
|
52
57
|
METHOD_OVERRIDE_PARAM_KEY = '_method'.freeze
|
53
58
|
|
@@ -134,3 +139,4 @@ class Rackful::MethodOverride
|
|
134
139
|
end
|
135
140
|
|
136
141
|
end # Rackful::MethodOverride
|
142
|
+
end # module Rackful
|
data/lib/rackful/parser.rb
CHANGED
@@ -1,77 +1,80 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
+
# Required for parsing:
|
4
|
+
require 'rackful/global.rb'
|
3
5
|
|
4
|
-
|
6
|
+
# Required for running:
|
5
7
|
|
8
|
+
module Rackful
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
# Base class for all concrete parsers defined in this library. You’ll probably
|
11
|
+
# want to use this class as the base class for your own parsers, too.
|
12
|
+
#
|
13
|
+
# This class mixes in module `StatusCodes` for convenience, as explained in the
|
14
|
+
# {StatusCodes StatusCodes documentation}.
|
15
|
+
# @abstract Subclasses must implement classmethod `::parse` with signature
|
16
|
+
# `(void) parse( Request, Response, Resource )`
|
17
|
+
# explained in {Resource::ClassMethods::add_parser}
|
18
|
+
# @example Subclassing this class
|
19
|
+
# class MyTextParser < Rackful::Parser
|
20
|
+
# parses 'text/*', 'application/xhtml+xml'
|
21
|
+
# def self.parse request, response, resource
|
22
|
+
# # YOUR CODE HERE...
|
23
|
+
# end
|
24
|
+
# end
|
19
25
|
class Parser
|
26
|
+
include StatusCodes
|
27
|
+
class << self
|
28
|
+
# @api private
|
29
|
+
def media_types
|
30
|
+
@media_types ||= begin
|
31
|
+
retval = rackful_parser_media_types
|
32
|
+
if superclass.respond_to?(:media_types)
|
33
|
+
retval += superclass.media_types
|
34
|
+
end
|
35
|
+
retval.uniq
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @overload parses( media_type, ... )
|
40
|
+
# @param media_type [String]
|
41
|
+
def parses *args
|
42
|
+
rackful_parser_media_types.unshift(
|
43
|
+
*( args.map { |mt| mt.to_s }.reverse )
|
44
|
+
)
|
45
|
+
rackful_parser_media_types.uniq!
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
def rackful_parser_media_types
|
51
|
+
@rackful_parser_media_types ||= []
|
52
|
+
end
|
53
|
+
end # class << self # Rackful::Parser
|
20
54
|
|
55
|
+
end # class Rackful::Parser
|
21
56
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
=end
|
26
|
-
|
27
|
-
|
28
|
-
# @return [Request]
|
29
|
-
attr_reader :request
|
30
|
-
# @return [Resource]
|
31
|
-
attr_reader :resource
|
32
|
-
|
33
|
-
|
34
|
-
=begin markdown
|
35
|
-
@param request [Request]
|
36
|
-
@param resource [Resource]
|
37
|
-
=end
|
38
|
-
def initialize request, resource
|
39
|
-
@request, @resource = request, resource
|
40
|
-
end
|
41
|
-
|
42
|
-
|
43
|
-
end # class Parser
|
44
|
-
|
45
|
-
|
46
|
-
=begin markdown
|
47
|
-
Parent class of all XML-parsing parsers.
|
48
|
-
@abstract
|
49
|
-
@since 0.2.0
|
50
|
-
=end
|
57
|
+
# Parent class of all XML-parsing parsers.
|
58
|
+
# @abstract
|
59
|
+
# @since 0.2.0
|
51
60
|
class Parser::DOM < Parser
|
52
61
|
|
62
|
+
# The media types parsed by this parser.
|
63
|
+
# @see Parser
|
64
|
+
parses 'text/xml', 'application/xml'
|
53
65
|
|
54
|
-
=begin markdown
|
55
|
-
The media types parsed by this parser.
|
56
|
-
@see Parser
|
57
|
-
=end
|
58
|
-
MEDIA_TYPES = [
|
59
|
-
'text/xml',
|
60
|
-
'application/xml'
|
61
|
-
]
|
62
66
|
|
67
|
+
def self.parse request, response, resource
|
68
|
+
self.new(request).parse( response, resource )
|
69
|
+
end
|
63
70
|
|
64
|
-
|
65
|
-
@return [Nokogiri::XML::Document]
|
66
|
-
=end
|
71
|
+
# @return [Nokogiri::XML::Document]
|
67
72
|
attr_reader :document
|
73
|
+
attr_reader :request
|
68
74
|
|
69
|
-
|
70
|
-
|
71
|
-
@
|
72
|
-
=end
|
73
|
-
def initialize request, resource
|
74
|
-
super request, resource
|
75
|
+
# @raise [HTTP400BadRequest] if the document is malformed.
|
76
|
+
def initialize request
|
77
|
+
@request = request
|
75
78
|
# TODO Is ISO-8859-1 indeed the default encoding for XML documents? If so,
|
76
79
|
# that fact must be documented and referenced.
|
77
80
|
encoding = self.request.media_type_params['charset'] || 'ISO-8859-1'
|
@@ -88,31 +91,21 @@ The media types parsed by this parser.
|
|
88
91
|
end
|
89
92
|
raise( HTTP400BadRequest, $!.to_s ) unless @document.root
|
90
93
|
end
|
94
|
+
|
95
|
+
end # class Rackful::Parser::DOM
|
91
96
|
|
92
97
|
|
93
|
-
end # class Parser::DOM
|
94
98
|
|
95
99
|
|
96
|
-
|
97
|
-
Parses XHTML as generated by {Serializer::XHTML}.
|
98
|
-
=end
|
100
|
+
# Parses XHTML as generated by {Serializer::XHTML}.
|
99
101
|
class Parser::XHTML < Parser::DOM
|
100
102
|
|
101
103
|
|
102
|
-
|
103
|
-
The media types parsed by this parser.
|
104
|
-
@see Parser
|
105
|
-
=end
|
106
|
-
MEDIA_TYPES = Parser::DOM::MEDIA_TYPES + [
|
107
|
-
'application/xhtml+xml',
|
108
|
-
'text/html'
|
109
|
-
]
|
104
|
+
parses 'application/xhtml+xml', 'text/html'
|
110
105
|
|
111
106
|
|
112
|
-
|
113
|
-
|
114
|
-
=end
|
115
|
-
def parse
|
107
|
+
# @see Parser#parse
|
108
|
+
def parse response, resource
|
116
109
|
# Try to find the actual content:
|
117
110
|
content = self.document.root.xpath(
|
118
111
|
'//html:div[@id="rackful-content"]',
|
@@ -139,13 +132,11 @@ The media types parsed by this parser.
|
|
139
132
|
end
|
140
133
|
end
|
141
134
|
# Parse the f*cking thing:
|
142
|
-
self.parse_recursive content.first
|
135
|
+
resource.to_rackful = self.parse_recursive content.first
|
143
136
|
end
|
144
137
|
|
145
138
|
|
146
|
-
|
147
|
-
@api private
|
148
|
-
=end
|
139
|
+
# @api private
|
149
140
|
def parse_recursive node
|
150
141
|
|
151
142
|
# A URI:
|
@@ -181,9 +172,7 @@ The media types parsed by this parser.
|
|
181
172
|
end
|
182
173
|
|
183
174
|
|
184
|
-
|
185
|
-
@api private
|
186
|
-
=end
|
175
|
+
# @api private
|
187
176
|
def parse_simple_type node, typename
|
188
177
|
case typename
|
189
178
|
when 'boolean'
|
@@ -208,9 +197,7 @@ The media types parsed by this parser.
|
|
208
197
|
end
|
209
198
|
|
210
199
|
|
211
|
-
|
212
|
-
@api private
|
213
|
-
=end
|
200
|
+
# @api private
|
214
201
|
def parse_object node
|
215
202
|
current_property = nil
|
216
203
|
r = {}
|
@@ -234,9 +221,7 @@ The media types parsed by this parser.
|
|
234
221
|
end
|
235
222
|
|
236
223
|
|
237
|
-
|
238
|
-
@api private
|
239
|
-
=end
|
224
|
+
# @api private
|
240
225
|
def parse_object_list node
|
241
226
|
properties = node.xpath(
|
242
227
|
'html:thead/html:tr/html:th',
|
@@ -273,22 +258,18 @@ end # class Parser::XHTML
|
|
273
258
|
class Parser::JSON < Parser
|
274
259
|
|
275
260
|
|
276
|
-
|
277
|
-
'application/json',
|
278
|
-
'application/x-json'
|
279
|
-
]
|
261
|
+
parses 'application/json', 'application/x-json'
|
280
262
|
|
281
|
-
|
282
|
-
def parse
|
263
|
+
def self.parse request, response, resource
|
283
264
|
r = ::JSON.parse(
|
284
|
-
|
265
|
+
request.env['rack.input'].read,
|
285
266
|
:symbolize_names => true
|
286
267
|
)
|
287
|
-
self.recursive_datetime_parser r
|
268
|
+
resource.to_rackful = self.recursive_datetime_parser r
|
288
269
|
end
|
289
270
|
|
290
271
|
|
291
|
-
def recursive_datetime_parser p
|
272
|
+
def self.recursive_datetime_parser p
|
292
273
|
if p.kind_of?(String)
|
293
274
|
begin
|
294
275
|
return Time.xmlschema(p)
|
@@ -297,12 +278,12 @@ class Parser::JSON < Parser
|
|
297
278
|
elsif p.kind_of?(Hash)
|
298
279
|
p.keys.each do
|
299
280
|
|key|
|
300
|
-
p[key] =
|
281
|
+
p[key] = recursive_datetime_parser( p[key] )
|
301
282
|
end
|
302
283
|
elsif p.kind_of?(Array)
|
303
284
|
(0 ... p.size).each do
|
304
285
|
|i|
|
305
|
-
p[i] =
|
286
|
+
p[i] = recursive_datetime_parser( p[i] )
|
306
287
|
end
|
307
288
|
end
|
308
289
|
p
|
@@ -310,6 +291,4 @@ class Parser::JSON < Parser
|
|
310
291
|
|
311
292
|
|
312
293
|
end # class Parser::JSON
|
313
|
-
|
314
|
-
|
315
294
|
end # module Rackful
|