Sha256: ab7576eb21ab04cef8d77a392bc35c32a8fe3361d40e6264e3cc11f71c187907

Contents?: true

Size: 1.78 KB

Versions: 6

Compression:

Stored size: 1.78 KB

Contents

require 'multi_json'

module Leadlight
  class Codec
    Strategy ||= Struct.new(:name, :encoder, :decoder, :patterns)

    def self.strategies
      @strategies ||= []
    end

    def self.strategy(name, encoder, decoder, patterns)
      strategies << Strategy.new(name, encoder, decoder, Array(patterns))
    end

    strategies.clear

    strategy :text,             
             ->(rep, options)         {rep.to_s},
             ->(entity_body, options) {entity_body},
             %r{^text/plain}

    strategy :json, 
             MultiJson.method(:encode),
             MultiJson.method(:decode), 
             [%r{^application/json}, %r{\+json$}]

    def decode(content_type, entity_body, options={})
      transcode(:decode, content_type, entity_body, options)
    end

    def encode(content_type, representation, options={})
      transcode(:encode, content_type, representation, options)
    end

    private

    def transcode(direction, content_type, input, options)
      fallback = unknown_type_handler(content_type)
      strategy = fetch_strategy(content_type, &fallback)
      transcoder = case direction
                   when :encode then strategy.encoder
                   when :decode then strategy.decoder
                   else raise ArgumentError, "Should never get here"
                   end
      transcoder.(input, options)
    end

    def strategies
      self.class.strategies
    end

    def fetch_strategy(content_type, &fallback)
      content_type = content_type.to_s.strip.split.first
      strategies.detect(fallback) { |strategy|
        strategy.patterns.any?{|pattern| pattern === content_type}
      }
    end

    def unknown_type_handler(content_type)
      -> do
        raise ArgumentError, "Unrecognized content type #{content_type.inspect}"
      end
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
leadlight-0.1.0 lib/leadlight/codec.rb
leadlight-0.0.7 lib/leadlight/codec.rb
leadlight-0.0.6 lib/leadlight/codec.rb
leadlight-0.0.5 lib/leadlight/codec.rb
leadlight-0.0.4 lib/leadlight/codec.rb
leadlight-0.0.3 lib/leadlight/codec.rb