File: map.rb

package info (click to toggle)
ruby-temple 0.10.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 476 kB
  • sloc: ruby: 3,347; makefile: 6
file content (106 lines) | stat: -rw-r--r-- 2,175 bytes parent folder | download | duplicates (2)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# frozen_string_literal: true
module Temple
  # Immutable map class which supports map merging
  # @api public
  class ImmutableMap
    include Enumerable

    def initialize(*map)
      @map = map.compact
    end

    def include?(key)
      @map.any? {|h| h.include?(key) }
    end

    def [](key)
      @map.each {|h| return h[key] if h.include?(key) }
      nil
    end

    def each
      keys.each {|k| yield(k, self[k]) }
    end

    def keys
      @map.inject([]) {|keys, h| keys.concat(h.keys) }.uniq
    end

    def values
      keys.map {|k| self[k] }
    end

    def to_hash
      result = {}
      each {|k, v| result[k] = v }
      result
    end
  end

  # Mutable map class which supports map merging
  # @api public
  class MutableMap < ImmutableMap
    def initialize(*map)
      super({}, *map)
    end

    def []=(key, value)
      @map.first[key] = value
    end

    def update(map)
      @map.first.update(map)
    end
  end

  class OptionMap < MutableMap
    def initialize(*map, &block)
      super(*map)
      @handler = block
      @valid = {}
      @deprecated = {}
    end

    def []=(key, value)
      validate_key!(key)
      super
    end

    def update(map)
      validate_map!(map)
      super
    end

    def valid_keys
      (keys + @valid.keys +
       @map.map {|h| h.valid_keys if h.respond_to?(:valid_keys) }.compact.flatten).uniq
    end

    def add_valid_keys(*keys)
      keys.flatten.each { |key| @valid[key] = true }
    end

    def add_deprecated_keys(*keys)
      keys.flatten.each { |key| @valid[key] = @deprecated[key] = true }
    end

    def validate_map!(map)
      map.to_hash.keys.each {|key| validate_key!(key) }
    end

    def validate_key!(key)
      @handler.call(self, key, :deprecated) if deprecated_key?(key)
      @handler.call(self, key, :invalid) unless valid_key?(key)
    end

    def deprecated_key?(key)
      @deprecated.include?(key) ||
        @map.any? {|h| h.deprecated_key?(key) if h.respond_to?(:deprecated_key?) }
    end

    def valid_key?(key)
      include?(key) || @valid.include?(key) ||
        @map.any? {|h| h.valid_key?(key) if h.respond_to?(:valid_key?) }
    end
  end
end