File: mapper.rb

package info (click to toggle)
ruby-mustermann19 0.4.3%2Bgit20160621-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 756 kB
  • ctags: 445
  • sloc: ruby: 7,197; makefile: 3
file content (98 lines) | stat: -rw-r--r-- 3,404 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
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
require 'mustermann'
require 'mustermann/expander'

module Mustermann
  # A mapper allows mapping one string to another based on pattern parsing and expanding.
  #
  # @example
  #   require 'mustermann/mapper'
  #   mapper = Mustermann::Mapper.new("/:foo" => "/:foo.html")
  #   mapper['/example'] # => "/example.html"
  class Mapper
    # Creates a new mapper.
    #
    # @overload initialize(**options)
    #   @param options [Hash] options The options hash
    #   @yield block for generating mappings as a hash
    #   @yieldreturn [Hash] see {#update}
    #
    #   @example
    #     require 'mustermann/mapper'
    #     Mustermann::Mapper.new(type: :rails) {{
    #       "/:foo" => ["/:foo.html", "/:foo.:format"]
    #     }}
    #
    # @overload initialize(**options)
    #   @param  options [Hash] options The options hash
    #   @yield block for generating mappings as a hash
    #   @yieldparam mapper [Mustermann::Mapper] the mapper instance
    #
    #   @example
    #     require 'mustermann/mapper'
    #     Mustermann::Mapper.new(type: :rails) do |mapper|
    #       mapper["/:foo"] = ["/:foo.html", "/:foo.:format"]
    #     end
    #
    # @overload initialize(map = {}, **options)
    #   @param map [Hash] see {#update}
    #   @param [Hash] options The options hash
    #
    #   @example map before options
    #     require 'mustermann/mapper'
    #     Mustermann::Mapper.new("/:foo" => "/:foo.html", type: :rails)
    #
    #   @example map after options
    #     require 'mustermann/mapper'
    #     Mustermann::Mapper.new(type: :rails, "/:foo" => "/:foo.html")
    def initialize(options = {}, &block)
      @map               = []
      @additional_values = options.delete(:additional_values) || :ignore
      @options           = options
      map = @options.inject({}) do |result, entry|
        result[entry[0]] = @options.delete(entry[0]) if entry[0].is_a?(String)
        result
      end
      block.arity == 0 ? update(yield) : yield(self) if block
      update(map) if map
    end

    # Add multiple mappings.
    #
    # @param map [Hash{String, Pattern: String, Pattern, Arry<String, Pattern>, Expander}] the mapping
    def update(map)
      map.to_hash.each_pair do |input, output|
        input  = Mustermann.new(input, @options.dup)
        output = Expander.new(*output, @options.merge(additional_values: @additional_values)) unless output.is_a? Expander
        @map << [input, output]
      end
    end

    # @return [Hash{Patttern: Expander}] Hash version of the mapper.
    def to_h
      Hash[@map]
    end

    # Convert a string according to mappings. You can pass in additional params.
    #
    # @example mapping with and without additional parameters
    #   mapper = Mustermann::Mapper.new("/:example" => "(/:prefix)?/:example.html")
    #
    def convert(input, values = {})
      @map.inject(input) do |current, (pattern, expander)|
        params = pattern.params(current)
        params &&= Hash[values.merge(params).map { |k,v| [k.to_s, v] }]
        expander.expandable?(params) ? expander.expand(params) : current
      end
    end

    # Add a single mapping.
    #
    # @param key [String, Pattern] format of the input string
    # @param value [String, Pattern, Arry<String, Pattern>, Expander] format of the output string
    def []=(key, value)
      update key => value
    end

    alias_method :[], :convert
  end
end