Class: PlainRouter

Inherits:
Object
  • Object
show all
Defined in:
lib/plainrouter.rb,
lib/plainrouter/version.rb

Defined Under Namespace

Classes: Method

Constant Summary collapse

VERSION =
"0.0.1"

Instance Method Summary collapse

Constructor Details

#initializePlainRouter

Returns a new instance of PlainRouter.



4
5
6
7
# File 'lib/plainrouter.rb', line 4

def initialize
  @routes = []
  @compiled_regexp
end

Instance Method Details

#add(path_info, stuff) ⇒ Object



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
# File 'lib/plainrouter.rb', line 9

def add(path_info, stuff)
  nodes, captures = [], []
  regexp = Regexp.union(/{((?:\{[0-9,]+\}|[^{}]+)+)}/,
                        /:([A-Za-z0-9_]+)/,
                        /(\*)/,
                        /([^{:*]+)/)
  path_info.sub(/(^\/)/,'').split('/').each.with_index do |path, pos|
    match = {position: nil, value: nil}
    path.match(regexp).size.times do |index|
      last_match = Regexp.last_match(index)
      if last_match
        match[:value] = last_match
        match[:position] = index
      end
    end
    case match[:position]
    when 1 then
      captures[pos], pattern = match[:value].split(':')
      pattern = pattern ? "(#{pattern})" : "([^/]+)"
      nodes.push(pattern)
    when 2 then
      captures[pos] = match[:value]
      nodes.push("([^/]+)")
    when 3 then
      captures[pos] = '*'
      nodes.push("(.+)")
    else
      nodes.push(path)
    end
  end
  @routes.push({path: '/' + nodes.join('/'), stuff: stuff, captures: captures })
  self.compile
end

#compileObject



43
44
45
46
# File 'lib/plainrouter.rb', line 43

def compile
  regexps = @routes.map.with_index {|r, index| /(?<_#{index}>#{r[:path]})/}
  @compiled_regexp = /\A#{Regexp.union(regexps)}\z/
end

#match(path_info) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/plainrouter.rb', line 48

def match(path_info)
  return if @compiled_regexp.nil?
  match = path_info.match(@compiled_regexp)
  @routes.size.times do |i|
    if Regexp.last_match("_#{i}")
      response = {}
      stuff = @routes[i][:stuff]
      captures = @routes[i][:captures]
      path_info.gsub(/([^\/]+)/).with_index do |path, pos|
        response[captures[pos]] = path if captures[pos] != nil
      end
      if response.empty?
        return stuff
      else
        return stuff, response
      end
    end
  end
  return
end