Module: Sansomable

Defined in:
lib/sansom.rb

Constant Summary collapse

InvalidRouteError =
Class.new StandardError
HTTP_VERBS =
[:get,:head, :post, :put, :delete, :patch, :options, :link, :unlink, :trace].freeze
ROUTE_METHODS =
HTTP_VERBS+[:map]
RACK_HANDLERS =
["puma", "unicorn", "thin", "webrick"].freeze
NOT_FOUND =
[404, {}, ["Not found."]].freeze

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/sansom.rb', line 84

def method_missing meth, *args, &block
  path, item = *args.dup.push(block)
  return super unless path && item
  return super unless item != self
  return super unless ROUTE_METHODS.include? meth
  tree.map_path path, item, meth
end

Instance Method Details

#after(&block) ⇒ Object



80
81
82
# File 'lib/sansom.rb', line 80

def after &block
  @after_block = block
end

#before(&block) ⇒ Object



76
77
78
# File 'lib/sansom.rb', line 76

def before &block
  @before_block = block
end

#call(env) ⇒ Object



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

def call env
  return NOT_FOUND if tree.leaf? && tree.root?

  r = Rack::Request.new env
  m = tree.match r.path_info, r.request_method

  return NOT_FOUND if m.nil?
  
  begin
    if @before_block && @before_block.arity == 1
      bres = @before_block.call r
      return bres if Rack::Fastlint.response bres
    end

    if m.url_params.count > 0
      q = r.params.merge m.url_params
      s = q.map { |p| p.join '=' }.join '&'
      r.env["rack.request.query_hash"] = q
      r.env["rack.request.query_string"] = s
      r.env["QUERY_STRING"] = s
      r.instance_variable_set "@params", r.POST.merge(q)
    end
  
    case m.item
    when Proc then res = m.item.call r
    else
      raise InvalidRouteError, "Route handlers must be blocks or valid rack apps." unless m.item.respond_to? :call
      r.env["PATH_INFO"] = m.remaining_path
      res = m.item.call r.env
    end
  
    if @after_block && @after_block.arity == 2
      ares = @after_block.call r, res
      return ares if Rack::Fastlint.response ares
    end
  
    res
  rescue StandardError => e
    b = (@error_blocks[e.class] || @error_blocks[:default]) rescue nil
    raise e if b.nil?
    b.call e, r
  end
end

#error(error_key = :default, &block) ⇒ Object



71
72
73
74
# File 'lib/sansom.rb', line 71

def error error_key=:default, &block
  @error_blocks ||= {}
  @error_blocks[error_key] = block
end

#start(port = 3001) ⇒ Object

Raises:

  • (NoRoutesError)


66
67
68
69
# File 'lib/sansom.rb', line 66

def start port=3001
  raise NoRoutesError if tree.leaf?
  Rack::Handler.pick(RACK_HANDLERS).run self, :Port => port
end

#treeObject



14
15
16
17
18
19
20
# File 'lib/sansom.rb', line 14

def tree
  if @tree.nil?
    @tree = Pine::Node.new "ROOT"
    template if respond_to? :template
  end
  @tree
end