Sha256: 365c7f40f686971b55dae83e306bb7c55bc48c3cf0144e270370a41de96bdf35

Contents?: true

Size: 1.05 KB

Versions: 2

Compression:

Stored size: 1.05 KB

Contents

require "active_enumerable/extract_options"

module ActiveEnumerable
  # @private
  module Order
    class << self
      def call(args, all)
        options = args.extract_options!
        if options.empty? && args.count == 1
          all.sort_by { |item| MethodCaller.new(item).call(args.first) }
        else
          order_mixed_args(all, args, options)
        end
      end

      private

      def order_mixed_args(all, args, options)
        normalized_opt = args.each_with_object({}) { |a, h| h[a] = :asc }.merge(options) # Add non specified direction keys
        all.sort { |a, b| build_order(a, normalized_opt) <=> build_order(b, normalized_opt) }
      end

      def build_order(a, options)
        options.map { |k, v| send(v, MethodCaller.new(a).call(k)) }
      end

      def desc(r)
        DESC.new(r)
      end

      def asc(r)
        r
      end
    end

    class DESC
      attr_reader :r

      def initialize(r)
        @r = r
      end

      def <=>(other)
        -(r <=> other.r) # Flip negative/positive result
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
active_enumerable-1.1.0 lib/active_enumerable/order.rb
active_enumerable-1.0.0 lib/active_enumerable/order.rb