lib/qeweney/routing.rb
# frozen_string_literal: true module Qeweney def self.route(&block) ->(r) { r.route(&block) } end module RoutingMethods def route(&block) @path_parts ||= path.split('/') @path_parts_idx ||= 1 res = catch(:stop) { yield self } return if res == :found respond(nil, ':status' => 404) end def route_found(&block) catch(:stop, &block) throw :stop, :found end @@regexp_cache = {} def route_part @path_parts[@path_parts_idx] end def route_relative_path @path_parts.empty? ? '/' : "/#{@path_parts[@path_parts_idx..-1].join('/')}" end def enter_route(depth = 1) @path_parts_idx += depth end def leave_route(depth = 1) @path_parts_idx -= depth end def on(route, &block) return route_found(&block) unless route route_parts = route.split('/') route_length = route_parts.size return unless @path_parts[@path_parts_idx, route_length] == route_parts enter_route(route_length) route_found(&block) leave_route(route_length) end def is(route = '/', &block) return unless @path_parts[@path_parts_idx] == route && @path_parts_idx >= @path_parts.size route_found(&block) end def on_root(&block) return unless @path_parts_idx > @path_parts.size - 1 route_found(&block) end def on_host(route, &block) return unless host == route route_found(&block) end def on_plain_http(route, &block) return unless scheme == 'http' route_found(&block) end def on_get(route = nil, &block) return unless method == 'get' on(route, &block) end def on_post(route = nil, &block) return unless method == 'post' on(route, &block) end def on_options(route = nil, &block) return unless method == 'options' on(route, &block) end def on_query_param(key) value = query[key] return unless value route_found { yield value } end def on_accept(accept, &block) if accept.is_a?(Regexp) return unless headers['accept'] =~ accept else return unless headers['accept'] == accept end route_found(&block) end def on_upgrade(protocol, &block) return unless upgrade_protocol == protocol route_found(&block) end def on_websocket_upgrade(&block) on_upgrade('websocket', &block) end def reject(body, status) respond(body, ':status' => status) throw :stop, :found end def stop_routing throw :stop, :found end def default yield throw :stop, :found end end end