Sha256: ea852ebcd097a37b1b09ff66d6047aa02ab7de4d92c338bdec6e4f8d30a24157

Contents?: true

Size: 1.46 KB

Versions: 7

Compression:

Stored size: 1.46 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

  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 || self.class.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

7 entries across 7 versions & 1 rubygems

Version Path
rest-core-0.8.0 lib/rest-core/wrapper.rb
rest-core-0.7.2 lib/rest-core/wrapper.rb
rest-core-0.7.0 lib/rest-core/wrapper.rb
rest-core-0.4.0 lib/rest-core/wrapper.rb
rest-core-0.4.0.pre.2 lib/rest-core/wrapper.rb
rest-core-0.4.0.pre.1 lib/rest-core/wrapper.rb
rest-core-0.4.0.pre.0 lib/rest-core/wrapper.rb