File: object.rb

package info (click to toggle)
ruby-glob 0.4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 200 kB
  • sloc: ruby: 449; makefile: 7; sh: 4
file content (71 lines) | stat: -rw-r--r-- 1,607 bytes parent folder | download
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
# frozen_string_literal: true

module Glob
  class Object
    PATH_SPLIT_RE = /(?<!\\)\./.freeze

    attr_reader :matchers

    def initialize(target)
      @target = target
      @matchers = []
    end

    def <<(path)
      matchers << Matcher.new(path)
    end
    alias filter <<

    def to_h
      symbolized_target = SymbolizeKeys.call(@target)

      paths.each_with_object({}) do |path, buffer|
        segments = path.split(PATH_SPLIT_RE).map {|key| unescape(key).to_sym }
        value = symbolized_target.dig(*segments)
        set_path_value(segments, buffer, value)
      end
    end
    alias to_hash to_h

    def set(path, value)
      set_path_value(path.split(PATH_SPLIT_RE), @target, value)
      @map = Map.call(@target)

      nil
    end

    def paths
      matches = map.map do |path|
        results = matchers.select {|matcher| matcher.match?(path) } # rubocop:disable Style/SelectByRegexp
        [path, results]
      end

      matches
        .select {|(_, results)| results.compact.last&.include? }
        .map {|(path)| path }
        .sort
    end

    private def map
      @map ||= Map.call(@target)
    end

    private def unescape(key)
      key.to_s.gsub("\\.", ".")
    end

    private def set_path_value(segments, target, value)
      segments = segments.dup.map(&:to_sym)

      while (segment = segments.shift)
        if segments.empty?
          target[segment] = value
        else
          target[segment] ||= {}
          target[segment] = {} unless target[segment].is_a?(Hash)
          target = target[segment]
        end
      end
    end
  end
end