File: struct.rb

package info (click to toggle)
mikutter 4.1.3%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 9,260 kB
  • sloc: ruby: 20,126; sh: 183; makefile: 19
file content (57 lines) | stat: -rw-r--r-- 1,900 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# -*- coding: utf-8 -*-

module Plugin::Spell

  Spell = Struct.new(:name, :constraint, :condition, :proc) do
    def match(models, optional)
      Set.new(constraint.map{|a| Diva::Model(a) }) == Set.new(models.map{|a| a.class }) and condition?(models, optional)
    end

    def call(models, optional)
      call_spell_block(models, optional, &proc)
    end

    def condition?(models, optional)
      if condition
        call_spell_block(models, optional, exception_message: false, &condition)
      else
        true
      end
    rescue Plugin::Spell::ArgumentError => err
      false
    end

    def to_s
      "#{name}[#{constraint.to_a.join(',')}]"
    end

    private
    def call_spell_block(models, optional, exception_message: true, &block)
      order = constraint.map{|a| Diva::Model(a) }
      models_sorted = models.sort_by{|m| order.index(m.class) }
      optional ||= {}.freeze
      args = Array.new
      kwargs = Hash.new
      block.parameters.each do |kind, name|
        case kind
        when :req, :opt
          raise Plugin::Spell::ArgumentError, exception_message && "too few argument (expect: #{block.arity}, given: #{models.size}) for #{self}" if models_sorted.empty?
          args << models_sorted.shift
        when :keyreq
          raise Plugin::Spell::ArgumentError, exception_message && "required option #{name} of #{self} was not set." unless optional.has_key?(name)
          kwargs[name] = optional[name]
        when :key
          kwargs[name] = optional[name] if optional.has_key?(name)
        when :keyrest
          kwargs = optional
        end
      end
      raise Plugin::Spell::ArgumentError, exception_message && "too many argument (expect: #{block.arity}, given: #{models.size}) for #{self}" unless models_sorted.empty?
      if kwargs.empty?
        block.call(*args)
      else
        block.call(*args, **kwargs)
      end
    end
  end
end