class HmlonsWeb::Router

Public Class Methods

new(&block) click to toggle source
# File lib/hmlons_web/router.rb, line 8
def initialize(&block)
  @routes = []
  instance_exec(&block)
end

Public Instance Methods

call(env) click to toggle source
# File lib/hmlons_web/router.rb, line 2
def call(env)
  find_route(env).call(env)
end

Private Instance Methods

extract_params(pattern, path) click to toggle source

/post/:name /post/test_one { name: 'test_one' }

# File lib/hmlons_web/router.rb, line 62
def extract_params(pattern, path)
  pattern
    .split('/') # ['post', ':name']
    .zip(path.split('/')) # [['post', 'post'],[':name', 'post']]
    .reject { |e| e.first == e.last } # [[':name', 'post']]
    .map { |e| [e.first[1..-1], e.last] } # [['name', 'post']]
    .to_h
end
find_route(env) click to toggle source
# File lib/hmlons_web/router.rb, line 13
def find_route(env)
  @routes.each do |route|
    if env['REQUEST_METHOD'] == route[:method] && env['REQUEST_PATH'] =~ route[:regexp]
      env['router.params'] = extract_params(route[:pattern], env['REQUEST_PATH'])
      return route[:app]
    end
  end

  return ->(_env) { [404, {}, ['page not found']] }
end
get(path, rack_app) click to toggle source
# File lib/hmlons_web/router.rb, line 24
def get(path, rack_app)
  match('GET', path, rack_app)
end
get_controller_action(str) click to toggle source
# File lib/hmlons_web/router.rb, line 37
def get_controller_action(str)
  controller_name, action_name = str.split('#') # tests#show => ['tests', 'show']
  controller_name = to_upper_camel_case(controller_name)
  Kernel.const_get(controller_name).send(:action, action_name)
  # controller_name = public_test
  # action_name = show
  # PublicTestController.action('show')
end
match(http_method, path, rack_app) click to toggle source
# File lib/hmlons_web/router.rb, line 32
def match(http_method, path, rack_app)
  rack_app = get_controller_action(rack_app) if rack_app.is_a?(String)
  @routes << { pattern: path, app: rack_app, regexp: path_to_regexp(path), method: http_method }
end
path_to_regexp(path) click to toggle source

/post/:name

# File lib/hmlons_web/router.rb, line 55
def path_to_regexp(path)
  Regexp.new('\A' + path.gsub(/:[\w-]+/, '[\w-]+') + '\Z')
end
post(path, rack_app) click to toggle source
# File lib/hmlons_web/router.rb, line 28
def post(path, rack_app)
  match('POST', path, rack_app)
end
to_upper_camel_case(str) click to toggle source
# File lib/hmlons_web/router.rb, line 46
def to_upper_camel_case(str)
  str # 'public_pages/tests' => PublicPages::TestsController
    .split('/') # ['public_pages', 'test']
    .map { |part| part.split('_').map(&:capitalize).join } # ['PublicPages', 'Test']
    .join('::') + 'Controller'
end