Sha256: 3a18b310e71c68042c1d345d1ad1beed02e13f74ab07a1fb50e85fb54cd47dff

Contents?: true

Size: 1.54 KB

Versions: 4

Compression:

Stored size: 1.54 KB

Contents

require 'rest-core'

module RestCore::Wrapper
  include RestCore
  def self.included mod
    mod.send(:attr_reader, :init, :middles, :wrapped)
    class << mod
      attr_writer :default_app
      def default_app
        @default_app ||= RestCore::Dry
      end
    end
  end

  attr_writer :default_app
  def default_app
    @default_app ||= self.class.default_app
  end

  def initialize &block
    @middles ||= []
    instance_eval(&block) if block_given?
    @wrapped ||= to_app
  end

  def use middle, *args, &block
    middles << [middle, args, block]
  end

  def run app
    @init = app
  end

  def members
    middles.map{ |(middle, args, block)|
      if middle.public_method_defined?(:wrapped)
        # TODO: this is hacky... try to avoid calling new!
        middle.members + middle.new(Dry.new, *args, &block).members
      else
        middle.members
      end if middle.respond_to?(:members)
    }.flatten
  end

  def to_app init=@init || default_app
    # === foldr m.new app middles
    middles.reverse.inject(init.new){ |app_, (middle, args, block)|
      begin
        middle.new(app_, *partial_deep_copy(args), &block)
      rescue ArgumentError => e
        raise ArgumentError.new("#{middle}: #{e}")
      end
    }
  end

  module_function
  def partial_deep_copy obj
    case obj
      when Array; obj.map{ |o| partial_deep_copy(o) }
      when Hash ; obj.inject({}){ |r, (k, v)| r[k] = partial_deep_copy(v); r }
      when Numeric, Symbol, TrueClass, FalseClass, NilClass; obj
      else begin obj.dup; rescue TypeError; obj; end
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
rest-core-1.0.1 lib/rest-core/wrapper.rb
rest-core-1.0.0 lib/rest-core/wrapper.rb
rest-core-0.8.2 lib/rest-core/wrapper.rb
rest-core-0.8.1 lib/rest-core/wrapper.rb