Sha256: e6d084bb1e68f996149a0168e60337d4f700febc22690fcd9a8115113090a391

Contents?: true

Size: 1.56 KB

Versions: 1

Compression:

Stored size: 1.56 KB

Contents

module Bmg
  module Ordering

    # Factory over subclasses
    def self.new(arg)
      case arg
      when Ordering
        arg
      when Proc
        Native.new(arg)
      else
        Attributes.new(arg)
      end
    end

    def call(t1, t2)
      comparator.call(t1, t2)
    end

    def to_a
      to_pairs
    end

    def map(*args, &bl)
      to_pairs.map(*args, &bl)
    end

    class Native
      include Ordering

      def initialize(comparator)
        @comparator = comparator
      end
      attr_reader :comparator

      def to_pairs
        raise Bmg::NotSupportedError
      end

    end # class Native

    class Attributes
      include Ordering

      def initialize(attrs)
        @attrs = if attrs.empty?
          []
        else
          attrs.map{|a| a.is_a?(Symbol) ? [a, :asc] : a }
        end
      end
      attr_reader :attrs

      def comparator
        @comparator ||= ->(t1, t2) { compare_attrs(t1, t2) }
      end

      def to_pairs
        attrs.to_a
      end

    private

      def compare_attrs(t1, t2)
        attrs.each do |(attr,direction)|
          a1, a2 = t1[attr], t2[attr]
          if a1.nil? && a2.nil?
            0
          elsif a1.nil?
            return direction == :desc ? -1 : 1
          elsif a2.nil?
            return direction == :desc ? 1 : -1
          elsif a1.respond_to?(:<=>)
            c = a1 <=> a2
            unless c.nil? || c==0
              return direction == :desc ? -c : c
            end
          end
        end
        0
      end

    end # class Attributes
  end # module Ordering
end # module Bmg

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
bmg-0.23.3 lib/bmg/support/ordering.rb