Sha256: 22107c0a14a1ed1db233541449a20a2a2c8f924f225ef6ed8771edd3cde1d835

Contents?: true

Size: 1.76 KB

Versions: 3

Compression:

Stored size: 1.76 KB

Contents

require 'hanami/routing/parsing/parser'

module Hanami
  module Routing
    class Parsers
      CONTENT_TYPE       = 'CONTENT_TYPE'.freeze
      MEDIA_TYPE_MATCHER = /\s*[;,]\s*/.freeze

      RACK_INPUT    = 'rack.input'.freeze
      ROUTER_PARAMS = 'router.params'.freeze
      FALLBACK_KEY  = '_'.freeze

      def initialize(parsers)
        @parsers = prepare(parsers)
        _redefine_call
      end

      def call(env)
        env
      end

      private
      def prepare(args)
        result  = Hash.new
        args    = Array(args)
        return result if args.empty?

        args.each do |arg|
          parser = Parsing::Parser.for(arg)

          parser.mime_types.each do |mime|
            result[mime] = parser
          end
        end

        result.default = Parsing::Parser.new
        result
      end

      def _redefine_call
        return if @parsers.empty?

        define_singleton_method :call do |env|
          body = env[RACK_INPUT].read
          return env if body.empty?

          env[RACK_INPUT].rewind    # somebody might try to read this stream

          env[ROUTER_PARAMS] ||= {} # prepare params
          env[ROUTER_PARAMS].merge!(
            _parse(env, body)
          )

          env
        end
      end

      def _parse(env, body)
        result = @parsers[
          media_type(env)
        ].parse(body)

        case result
        when Hash
          result
        else
          {FALLBACK_KEY => result}
        end
      end

      def media_type(env)
        if ct = content_type(env)
          ct.split(MEDIA_TYPE_MATCHER, 2).first.downcase
        end
      end

      def content_type(env)
        content_type = env[CONTENT_TYPE]
        content_type.nil? || content_type.empty? ? nil : content_type
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
hanami-router-0.7.0 lib/hanami/routing/parsers.rb
hanami-router-0.6.2 lib/hanami/routing/parsers.rb
hanami-router-0.6.1 lib/hanami/routing/parsers.rb