lib/grape/middleware/formatter.rb in grape-0.0.0.alpha.2 vs lib/grape/middleware/formatter.rb in grape-0.1.0
- old
+ new
@@ -1,32 +1,41 @@
require 'grape/middleware/base'
-require 'active_support/json'
+require 'multi_json'
module Grape
module Middleware
class Formatter < Base
CONTENT_TYPES = {
:xml => 'application/xml',
:json => 'application/json',
:atom => 'application/atom+xml',
- :rss => 'application/rss+xml'
+ :rss => 'application/rss+xml',
+ :txt => 'text/plain'
}
def default_options
{
- :default_format => :json,
+ :default_format => :txt,
:content_types => {}
}
end
def content_types
CONTENT_TYPES.merge(options[:content_types])
end
+ def mime_types
+ content_types.invert
+ end
+
+ def headers
+ env.dup.inject({}){|h,(k,v)| h[k.downcase] = v; h}
+ end
+
def before
fmt = format_from_extension || format_from_header || options[:default_format]
-
+
if content_types.key?(fmt)
env['api.format'] = fmt
else
throw :error, :status => 406, :message => 'The requested format is not supported.'
end
@@ -42,18 +51,56 @@
hit
end
end
def format_from_header
- # TODO: Implement Accept header parsing.
+ mime_array.each do |t|
+ if mime_types.key?(t)
+ return mime_types[t]
+ end
+ end
+ nil
end
+ def mime_array
+ accept = headers['accept']
+ if accept
+ accept.gsub(/\b/,'').
+ scan(/(\w+\/[\w+]+)(?:;[^,]*q=([0-9.]+)[^,]*)?/i).
+ sort_by{|a| -a[1].to_f}.
+ map{|a| a[0]}
+ else
+ []
+ end
+ end
+
def after
status, headers, bodies = *@app_response
- bodies.map! do |body|
- ActiveSupport::JSON.encode(body)
+ bodymap = []
+ bodies.each do |body|
+ bodymap << case env['api.format']
+ when :json
+ encode_json(body)
+ when :txt
+ encode_txt(body)
+ end
end
- [status, headers, bodies]
+ headers['Content-Type'] = 'application/json'
+ Rack::Response.new(bodymap, status, headers).to_a
+ end
+
+ def encode_json(object)
+ if object.respond_to? :serializable_hash
+ MultiJson.encode(object.serializable_hash)
+ elsif object.respond_to? :to_json
+ object.to_json
+ else
+ MultiJson.encode(object)
+ end
+ end
+
+ def encode_txt(object)
+ body.respond_to?(:to_txt) ? body.to_txt : body.to_s
end
end
end
end
\ No newline at end of file