hanami-router 2.0.0.alpha3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,10 +4,13 @@ module Hanami
4
4
  class Router
5
5
  # Represents a result of router path recognition.
6
6
  #
7
- # @since 0.5.0
8
- #
9
7
  # @see Hanami::Router#recognize
8
+ #
9
+ # @since 0.5.0
10
+ # @api public
10
11
  class RecognizedRoute
12
+ # @since 0.5.0
13
+ # @api private
11
14
  def initialize(endpoint, env)
12
15
  @endpoint = endpoint
13
16
  @env = env
@@ -27,7 +30,7 @@ module Hanami
27
30
  # @see Hanami::Router::RecognizedRoute#routable?
28
31
  # @see Hanami::Router::NotRoutableEndpointError
29
32
  def call(env)
30
- if routable? # rubocop:disable Style/GuardClause
33
+ if routable?
31
34
  @endpoint.call(env)
32
35
  else
33
36
  raise NotRoutableEndpointError.new(@env)
@@ -41,7 +44,7 @@ module Hanami
41
44
  # @since 0.5.0
42
45
  # @api public
43
46
  def verb
44
- @env["REQUEST_METHOD"]
47
+ @env[::Rack::REQUEST_METHOD]
45
48
  end
46
49
 
47
50
  # Relative URL (path)
@@ -51,15 +54,25 @@ module Hanami
51
54
  # @since 0.7.0
52
55
  # @api public
53
56
  def path
54
- @env["PATH_INFO"]
57
+ @env[::Rack::PATH_INFO]
55
58
  end
56
59
 
60
+ # Returns the route's path params.
61
+ #
62
+ # @return [Hash]
63
+ #
57
64
  # @since 0.7.0
58
65
  # @api public
59
66
  def params
60
- @env["router.params"]
67
+ @env[Router::PARAMS]
61
68
  end
62
69
 
70
+ # Returns the route's endpoint object.
71
+ #
72
+ # Returns nil if the route is a {#redirect? redirect}.
73
+ #
74
+ # @return [Object, nil]
75
+ #
63
76
  # @since 0.7.0
64
77
  # @api public
65
78
  def endpoint
@@ -68,18 +81,30 @@ module Hanami
68
81
  @endpoint
69
82
  end
70
83
 
84
+ # Returns true if the route has an {#endpoint}.
85
+ #
86
+ # @return [Boolean]
87
+ #
71
88
  # @since 0.7.0
72
89
  # @api public
73
90
  def routable?
74
91
  !@endpoint.nil?
75
92
  end
76
93
 
94
+ # Returns true if the route is a redirect.
95
+ #
96
+ # @return [Boolean]
97
+ #
77
98
  # @since 0.7.0
78
99
  # @api public
79
100
  def redirect?
80
101
  @endpoint.is_a?(Redirect)
81
102
  end
82
103
 
104
+ # Returns the route's redirect path, if it is a redirect, or nil otherwise.
105
+ #
106
+ # @return [String, nil]
107
+ #
83
108
  # @since 0.7.0
84
109
  # @api public
85
110
  def redirection_path
@@ -13,8 +13,13 @@ module Hanami
13
13
 
14
14
  # @since 2.0.0
15
15
  # @api private
16
- def initialize(destination, endpoint)
16
+ attr_reader :code
17
+
18
+ # @since 2.0.0
19
+ # @api private
20
+ def initialize(destination, code, endpoint)
17
21
  @destination = destination
22
+ @code = code
18
23
  @endpoint = endpoint
19
24
  end
20
25
 
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/router/redirect"
4
+ require "hanami/router/block"
5
+
6
+ module Hanami
7
+ class Router
8
+ # A route from the router
9
+ #
10
+ # @since 2.0.0
11
+ # @api public
12
+ class Route
13
+ # @since 2.0.0
14
+ # @api private
15
+ ROUTE_CONSTRAINT_SEPARATOR = ", "
16
+ private_constant :ROUTE_CONSTRAINT_SEPARATOR
17
+
18
+ # Returns the route's HTTP method.
19
+ #
20
+ # @example
21
+ # route.http_method # => "GET"
22
+ #
23
+ # @return [String]
24
+ #
25
+ # @since 2.0.0
26
+ # @api public
27
+ attr_reader :http_method
28
+
29
+ # Returns the route's path.
30
+ #
31
+ # @example
32
+ # route.path # => "/a/b/c"
33
+ #
34
+ # @return [String]
35
+ #
36
+ # @since 2.0.0
37
+ # @api public
38
+ attr_reader :path
39
+
40
+ # Returns the route's Rack endpoint, as given to `to:` when the route was defined.
41
+ #
42
+ # @return [Object]
43
+ #
44
+ # @since 2.0.0
45
+ # @api public
46
+ attr_reader :to
47
+
48
+ # Returns the route's unique name, as given to `as:` when the route was defined.
49
+ #
50
+ # @return [Object]
51
+ #
52
+ # @since 2.0.0
53
+ # @api public
54
+ attr_reader :as
55
+
56
+ # Returns the route's contraints hash for its path variables.
57
+ #
58
+ # @return [Hash]
59
+ #
60
+ # @since 2.0.0
61
+ # @api public
62
+ attr_reader :constraints
63
+
64
+ # @api private
65
+ # @since 2.0.0
66
+ def initialize(http_method:, path:, to:, as: nil, constraints: {}, blk: nil) # rubocop:disable Metrics/ParameterLists
67
+ @http_method = http_method
68
+ @path = path
69
+ @to = to
70
+ @as = as
71
+ @constraints = constraints
72
+ @blk = blk
73
+ freeze
74
+ end
75
+
76
+ # Returns true if the route is for the HEAD HTTP method.
77
+ #
78
+ # @return [Boolean]
79
+ #
80
+ # @see #http_method
81
+ #
82
+ # @since 2.0.0
83
+ # @api public
84
+ def head?
85
+ http_method == ::Rack::HEAD
86
+ end
87
+
88
+ # Returns true if the route has a name.
89
+ #
90
+ # @return [Boolean]
91
+ #
92
+ # @see #as
93
+ #
94
+ # @since 2.0.0
95
+ # @api public
96
+ def as?
97
+ !as.nil?
98
+ end
99
+
100
+ # Returns true if the route has any constraints.
101
+ #
102
+ # @return [Boolean]
103
+ #
104
+ # @see #constraints
105
+ #
106
+ # @since 2.0.0
107
+ # @api public
108
+ def constraints?
109
+ constraints.any?
110
+ end
111
+
112
+ # Returns a string containing a human-readable representation of the route's {#to} endpoint.
113
+ #
114
+ # @return [String]
115
+ #
116
+ # @since 2.0.0
117
+ # @api public
118
+ def inspect_to(value = to)
119
+ case value
120
+ when String
121
+ value
122
+ when Proc
123
+ "(proc)"
124
+ when Class
125
+ value.name || "(class)"
126
+ when Block
127
+ "(block)"
128
+ when Redirect
129
+ "#{value.destination} (HTTP #{to.code})"
130
+ else
131
+ inspect_to(value.class)
132
+ end
133
+ end
134
+
135
+ # Returns a string containing a human-readable representation of the route's {#constraints}.
136
+ #
137
+ # @return [String]
138
+ #
139
+ # @since 2.0.0
140
+ # @api public
141
+ def inspect_constraints
142
+ @constraints.map do |key, value|
143
+ "#{key}: #{value.inspect}"
144
+ end.join(ROUTE_CONSTRAINT_SEPARATOR)
145
+ end
146
+
147
+ # Returns a string containing a human-readable representation of the route's name.
148
+ #
149
+ # @return [String]
150
+ #
151
+ # @see #as
152
+ #
153
+ # @since 2.0.0
154
+ # @api public
155
+ def inspect_as
156
+ as ? as.inspect : Router::EMPTY_STRING
157
+ end
158
+ end
159
+ end
160
+ end
@@ -52,10 +52,15 @@ module Hanami
52
52
 
53
53
  private
54
54
 
55
+ # @api private
56
+ # @since 2.0.0
57
+ SEGMENT_SEPARATOR = /\//
58
+ private_constant :SEGMENT_SEPARATOR
59
+
55
60
  # @api private
56
61
  # @since 2.0.0
57
62
  def for_each_segment(path, &blk)
58
- _, *segments = path.split(/\//)
63
+ _, *segments = path.split(SEGMENT_SEPARATOR)
59
64
  segments.each(&blk)
60
65
  end
61
66
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "hanami/router/error"
3
+ require "hanami/router/errors"
4
4
  require "mustermann/error"
5
5
 
6
6
  module Hanami
7
7
  class Router
8
- # URL Helpers
8
+ # @since 2.0.0
9
+ # @api private
9
10
  class UrlHelpers
10
11
  # @since 2.0.0
11
12
  # @api private
@@ -21,17 +22,17 @@ module Hanami
21
22
  end
22
23
 
23
24
  # @since 2.0.0
24
- # @api public
25
+ # @api private
25
26
  def path(name, variables = {})
26
27
  @named.fetch(name.to_sym) do
27
- raise InvalidRouteException.new(name)
28
+ raise MissingRouteError.new(name)
28
29
  end.expand(:append, variables)
29
30
  rescue Mustermann::ExpandError => exception
30
- raise InvalidRouteExpansionException.new(name, exception.message)
31
+ raise InvalidRouteExpansionError.new(name, exception.message)
31
32
  end
32
33
 
33
34
  # @since 2.0.0
34
- # @api public
35
+ # @api private
35
36
  def url(name, variables = {})
36
37
  @base_url + path(name, variables)
37
38
  end
@@ -2,8 +2,11 @@
2
2
 
3
3
  module Hanami
4
4
  class Router
5
- # @since 0.1.0
5
+ # Returns the hanami-router version.
6
+ #
7
+ # @return [String]
8
+ #
6
9
  # @api public
7
- VERSION = "2.0.0.alpha3"
10
+ VERSION = "2.0.0"
8
11
  end
9
12
  end