roda 3.36.0 → 3.37.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abd198c51a38d272c8601fb367c12b9ad244f8383bcfb2f0583e7c7e23744eca
4
- data.tar.gz: 75cee1c957032abd4144f01fbd720794d2f66e7422514fa6e58b8bd5f8087b6e
3
+ metadata.gz: de8c769572875e477058b48557b22861b9de731fa3b00b20a3022a67c929609d
4
+ data.tar.gz: 5cacc0d7b988bd3dc5bafbc30fcac145f6f67ddcc0e7809e1fc9cd60d8a16273
5
5
  SHA512:
6
- metadata.gz: e3b7fed2ed29b869b205114d3bf644bb81f1f8d3a267682976aa4eef019e9ca015ade6526d75a99d5f6f1128991f70ba692e1c527acdc62874fbd39e49c24dba
7
- data.tar.gz: 341da7749e2432b1a3139f29b09f6a219480bb6984a74e121fc2b30bc4f7c4f7c6e51b1be01fb836ef85399cef1cfd15249495d335c80b44eed75a1a657960c7
6
+ metadata.gz: 1bf7df28d82f31820cd19c29b5a3f0f3afbbae2c41cf05974b16698c7ffb1725e924491874ddbb3f355a88990d4aab6d5b5b38f2d9c7612a548bfe0e3701ac2e
7
+ data.tar.gz: 32fca636d6324d29958cbcdf5c949c413eaeda7b74a701032d5766a60ec6b3f2db7ec262268dac697c3b3f5f9b183e127ddf265c7ba5015578969bc7f8be02a2
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 3.37.0 (2020-10-16)
2
+
3
+ * Add custom_matchers plugin, for supporting arbitrary objects as matchers (jeremyevans)
4
+
1
5
  = 3.36.0 (2020-09-14)
2
6
 
3
7
  * Add multi_public plugin, for serving files from multiple public directories (jeremyevans)
@@ -0,0 +1,42 @@
1
+ = New Features
2
+
3
+ * A custom_matchers plugin has been added, which allows using
4
+ arbitrary objects as matchers, as long as the matcher has been
5
+ registered. You can register matchers using the custom_matcher
6
+ class method, which takes the class of the matcher, and a block
7
+ which is yielded the matcher object. The block should return
8
+ nil or false if the matcher doesn't match, and any other value
9
+ if the matcher does match. Example:
10
+
11
+ plugin :custom_matchers
12
+ method_segment = Struct.new(:request_method, :next_segment)
13
+ custom_matcher(method_segment) do |matcher|
14
+ # self is the request instance ("r" yielded in the route block below)
15
+ if matcher.request_method == self.request_method
16
+ match(matcher.next_segment)
17
+ end
18
+ end
19
+
20
+ get_foo = method_segment.new('GET', 'foo')
21
+ post_any = method_segment.new('POST', String)
22
+ route do |r|
23
+ r.on('baz') do
24
+ r.on(get_foo) do
25
+ # GET method, /baz/foo prefix
26
+ end
27
+
28
+ r.is(post_any) do |seg|
29
+ # for POST /baz/bar, seg is "bar"
30
+ end
31
+ end
32
+
33
+ r.on('quux') do
34
+ r.is(get_foo) do
35
+ # GET method, /quux/foo route
36
+ end
37
+
38
+ r.on(post_any) do |seg|
39
+ # for POST /quux/xyz, seg is "xyz"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,87 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The custom_matchers plugin supports using arbitrary objects
7
+ # as matchers, as long as the application has been configured
8
+ # to accept such objects.
9
+ #
10
+ # After loading the plugin, support for custom matchers can be
11
+ # configured using the +custom_matcher+ class method. This
12
+ # method is generally passed the class of the object you want
13
+ # to use as a custom matcher, as well as a block. The block
14
+ # will be called in the context of the request instance
15
+ # with the specific matcher used in the match method.
16
+ #
17
+ # Blocks can append to the captures in order to yield the appropriate
18
+ # values to match blocks, or call request methods that append to the
19
+ # captures.
20
+ #
21
+ # Example:
22
+ #
23
+ # plugin :custom_matchers
24
+ # method_segment = Struct.new(:request_method, :next_segment)
25
+ # custom_matcher(method_segment) do |matcher|
26
+ # # self is the request instance ("r" yielded in the route block below)
27
+ # if matcher.request_method == self.request_method
28
+ # match(matcher.next_segment)
29
+ # end
30
+ # end
31
+ #
32
+ # get_foo = method_segment.new('GET', 'foo')
33
+ # post_any = method_segment.new('POST', String)
34
+ # route do |r|
35
+ # r.on('baz') do
36
+ # r.on(get_foo) do
37
+ # # GET method, /baz/foo prefix
38
+ # end
39
+ #
40
+ # r.is(post_any) do |seg|
41
+ # # for POST /baz/bar, seg is "bar"
42
+ # end
43
+ # end
44
+ #
45
+ # r.on('quux') do
46
+ # r.is(get_foo) do
47
+ # # GET method, /quux/foo route
48
+ # end
49
+ #
50
+ # r.on(post_any) do |seg|
51
+ # # for POST /quux/xyz, seg is "xyz"
52
+ # end
53
+ # end
54
+ # end
55
+ module CustomMatchers
56
+ def self.configure(app)
57
+ app.opts[:custom_matchers] ||= OPTS
58
+ end
59
+
60
+ module ClassMethods
61
+ def custom_matcher(match_class, &block)
62
+ custom_matchers = Hash[opts[:custom_matchers]]
63
+ meth = custom_matchers[match_class] = custom_matchers[match_class] || :"_custom_matcher_#{match_class}"
64
+ opts[:custom_matchers] = custom_matchers.freeze
65
+ self::RodaRequest.send(:define_method, meth, &block)
66
+ nil
67
+ end
68
+ end
69
+
70
+ module RequestMethods
71
+ # Try custom matchers before calling super
72
+ def unsupported_matcher(matcher)
73
+ roda_class.opts[:custom_matchers].each do |match_class, meth|
74
+ if match_class === matcher
75
+ return send(meth, matcher)
76
+ end
77
+ end
78
+
79
+ super
80
+ end
81
+ end
82
+ end
83
+
84
+ register_plugin(:custom_matchers, CustomMatchers)
85
+ end
86
+ end
87
+
@@ -609,10 +609,9 @@ class Roda
609
609
  when nil
610
610
  keys = (0...@obj.length)
611
611
 
612
- valid = case @obj
613
- when Array
612
+ valid = if @obj.is_a?(Array)
614
613
  true
615
- when Hash
614
+ else
616
615
  keys = keys.map(&:to_s)
617
616
  keys.all?{|k| @obj.has_key?(k)}
618
617
  end
@@ -4,7 +4,7 @@ class Roda
4
4
  RodaMajorVersion = 3
5
5
 
6
6
  # The minor version of Roda, updated for new feature releases of Roda.
7
- RodaMinorVersion = 36
7
+ RodaMinorVersion = 37
8
8
 
9
9
  # The patch version of Roda, updated only for bug fixes from the last
10
10
  # feature release.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.36.0
4
+ version: 3.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -212,6 +212,7 @@ extra_rdoc_files:
212
212
  - doc/release_notes/3.34.0.txt
213
213
  - doc/release_notes/3.35.0.txt
214
214
  - doc/release_notes/3.36.0.txt
215
+ - doc/release_notes/3.37.0.txt
215
216
  files:
216
217
  - CHANGELOG
217
218
  - MIT-LICENSE
@@ -249,6 +250,7 @@ files:
249
250
  - doc/release_notes/3.34.0.txt
250
251
  - doc/release_notes/3.35.0.txt
251
252
  - doc/release_notes/3.36.0.txt
253
+ - doc/release_notes/3.37.0.txt
252
254
  - doc/release_notes/3.4.0.txt
253
255
  - doc/release_notes/3.5.0.txt
254
256
  - doc/release_notes/3.6.0.txt
@@ -275,6 +277,7 @@ files:
275
277
  - lib/roda/plugins/content_security_policy.rb
276
278
  - lib/roda/plugins/cookies.rb
277
279
  - lib/roda/plugins/csrf.rb
280
+ - lib/roda/plugins/custom_matchers.rb
278
281
  - lib/roda/plugins/default_headers.rb
279
282
  - lib/roda/plugins/default_status.rb
280
283
  - lib/roda/plugins/delay_build.rb
@@ -387,7 +390,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
387
390
  - !ruby/object:Gem::Version
388
391
  version: '0'
389
392
  requirements: []
390
- rubygems_version: 3.1.2
393
+ rubygems_version: 3.1.4
391
394
  signing_key:
392
395
  specification_version: 4
393
396
  summary: Routing tree web toolkit