Class: Rack::Route

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/route.rb

Constant Summary collapse

PATH_INFO =
'PATH_INFO'.freeze
DEFAULT_WILDCARD_NAME =
:paths
WILDCARD_PATTERN =
/\/\*(.*)/.freeze
NAMED_SEGMENTS_PATTERN =
/\/:([^$\/]+)/.freeze
NAMED_SEGMENTS_REPLACEMENT_PATTERN =
/\/:([^$\/]+)/.freeze
DOT =
'.'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_method, pattern, app, options = {}) ⇒ Route

Returns a new instance of Route.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rack/route.rb', line 12

def initialize(request_method, pattern, app, options={})
  if pattern.to_s.strip.empty?
    raise ArgumentError.new("pattern cannot be blank")
  end

  unless app.respond_to?(:call)
    raise ArgumentError.new("app must be callable")
  end

  @request_method = request_method
  @pattern = pattern
  @app = app
  @constraints = options && options[:constraints]
  @name = options && options[:as]
end

Instance Attribute Details

#appObject

Returns the value of attribute app.



3
4
5
# File 'lib/rack/route.rb', line 3

def app
  @app
end

#constraintsObject

Returns the value of attribute constraints.



3
4
5
# File 'lib/rack/route.rb', line 3

def constraints
  @constraints
end

#nameObject

Returns the value of attribute name.



3
4
5
# File 'lib/rack/route.rb', line 3

def name
  @name
end

#patternObject

Returns the value of attribute pattern.



3
4
5
# File 'lib/rack/route.rb', line 3

def pattern
  @pattern
end

#request_methodObject

Returns the value of attribute request_method.



3
4
5
# File 'lib/rack/route.rb', line 3

def request_method
  @request_method
end

Instance Method Details

#compileObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/rack/route.rb', line 32

def compile
  src = if pattern_match = pattern.match(WILDCARD_PATTERN)
    @wildcard_name = if pattern_match[1].to_s.strip.empty?
      DEFAULT_WILDCARD_NAME
    else
      pattern_match[1].to_sym
    end
    pattern.gsub(WILDCARD_PATTERN,'(?:/(.*)|)')
  else
    p = if pattern_match = pattern.match(NAMED_SEGMENTS_PATTERN)
      pattern.gsub(NAMED_SEGMENTS_REPLACEMENT_PATTERN, '/(?<\1>[^.$/]+)')
    else
      pattern
    end
    p + '(?:\.(?<format>.*))?'
  end
  Regexp.new("\\A#{src}\\Z")
end

#eql?(o) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


86
87
88
89
90
91
92
# File 'lib/rack/route.rb', line 86

def eql?(o)
  o.is_a?(self.class) &&
    o.request_method == request_method &&
    o.pattern == pattern &&
    o.app == app &&
    o.constraints == constraints
end

#hashObject



95
96
97
# File 'lib/rack/route.rb', line 95

def hash
  request_method.hash ^ pattern.hash ^ app.hash ^ constraints.hash
end

#match(request_method, path) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rack/route.rb', line 51

def match(request_method, path)
  unless request_method == self.request_method
    return nil
  end

  if path.to_s.strip.empty?
    raise ArgumentError.new("path is required")
  end

  if path_match = path.match(regexp)
    params = if @wildcard_name
      { @wildcard_name => path_match[1].to_s.split('/') }
    else
      Hash[path_match.names.map(&:to_sym).zip(path_match.captures)]
    end

    params.delete(:format) if params.has_key?(:format) && params[:format].nil?

    if meets_constraints(params)
      params
    end
  end
end

#meets_constraints(params) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'lib/rack/route.rb', line 75

def meets_constraints(params)
  if constraints
    constraints.each do |param, constraint|
      unless params[param].to_s.match(constraint)
        return false
      end
    end
  end
  true
end

#regexpObject



28
29
30
# File 'lib/rack/route.rb', line 28

def regexp
  @regexp ||= compile
end