lib/sinatra/json.rb in sinatra-contrib-1.3.2 vs lib/sinatra/json.rb in sinatra-contrib-1.4.0

- old
+ new

@@ -42,12 +42,12 @@ # # The rest of your modular application code goes here... # end # # === Encoders # - # Per default it will try to call +to_json+ on the object, but if it doesn't - # respond to that message, will use its own, rather simple encoder. You can + # By default it will try to call +to_json+ on the object, but if it doesn't + # respond to that message, it will use its own rather simple encoder. You can # easily change that anyways. To use +JSON+, simply require it: # # require 'json' # # The same goes for <tt>Yajl::Encoder</tt>: @@ -88,46 +88,42 @@ # end # module JSON class << self def encode(object) - enc object, Array, Hash + ::MultiJson.dump(object) end + end - private + def json(object, options = {}) + content_type resolve_content_type(options) + resolve_encoder_action object, resolve_encoder(options) + end - def enc(o, *a) - o = o.to_s if o.is_a? Symbol - fail "invalid: #{o.inspect}" unless a.empty? or a.include? o.class - case o - when Float then o.nan? || o.infinite? ? 'null' : o.inspect - when TrueClass, FalseClass, NilClass, Numeric, String then o.inspect - when Array then map(o, "[%s]") { |e| enc(e) } - when Hash then map(o, "{%s}") { |k,v| enc(k, String) + ":" + enc(v) } - end - end + private - def map(o, wrapper, &block) - wrapper % o.map(&block).join(',') - end + def resolve_content_type(options = {}) + options[:content_type] || settings.json_content_type end - def json(object, options = {}) - encoder = options[:encoder] || settings.json_encoder - content_type options[:content_type] || settings.json_content_type - if encoder.respond_to? :encode then encoder.encode(object) - elsif encoder.respond_to? :generate then encoder.generate(object) - elsif encoder.is_a? Symbol then object.__send__(encoder) - else fail "#{encoder} does not respond to #generate nor #encode" - end + def resolve_encoder(options = {}) + options[:json_encoder] || settings.json_encoder end - end + def resolve_encoder_action(object, encoder) + [:encode, :generate].each do |method| + return encoder.send(method, object) if encoder.respond_to? method + end + if encoder.is_a? Symbol + object.__send__(encoder) + else + fail "#{encoder} does not respond to #generate nor #encode" + end #if + end #resolve_encoder_action + end #JSON + Base.set :json_encoder do - return Yajl::Encoder if defined? Yajl::Encoder - return JSON if defined? JSON - return :to_json if {}.respond_to? :to_json and [].respond_to? :to_json - Sinatra::JSON + ::MultiJson end Base.set :json_content_type, :json helpers JSON end