Sha256: 071ae4633bac8ee2eeb7c92cc7eba713b4b5272f6adc2e6bd11961b98a4aabb3

Contents?: true

Size: 1.34 KB

Versions: 2

Compression:

Stored size: 1.34 KB

Contents

require 'cl/arg'

module Cl
  class Args
    include Enumerable

    def define(const, name, opts = {})
      arg = Arg.new(name, opts)
      arg.define(const)
      args << arg
    end

    def apply(cmd, args)
      return args unless self.args.any?
      args = grouped(args)
      validate(args)
      args.map { |(arg, value)| arg.set(cmd, value) }.flatten(1)
    end

    def each(&block)
      args.each(&block)
    end

    def index(*args, &block)
      self.args.index(*args, &block)
    end

    def args
      @args ||= []
    end

    private

      def validate(args)
        raise ArgumentError.new(:missing_args, args.size, required) if args.size < required
        raise ArgumentError.new(:too_many_args, args.size, allowed) if args.size > allowed && !splat?
      end

      def allowed
        args.size
      end

      def splat?
        args.any?(&:splat?)
      end

      def required
        args.select { |arg| arg.required? }.size
      end

      def grouped(values)
        values.inject([0, {}]) do |(ix, group), value|
          arg = args[ix]
          if arg && arg.splat?
            group[arg] ||= []
            group[arg] << value
            ix += 1 if args.size + group[arg].size > values.size
          else
            group[arg] = value
            ix += 1
          end
          [ix, group]
        end.last
      end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
cl-0.0.4 lib/cl/args.rb
cl-0.0.3 lib/cl/args.rb