roda 3.66.0 → 3.67.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: 52a6bb08790a0a3414771a5d772a27d98089a96a306812ddb781ce31724289f0
4
- data.tar.gz: 8679931319b2abf3b8aba64151664cf2d154517fbfd5020ded910e5ba32452a0
3
+ metadata.gz: 0ea9212a800294ebf286d593e230ac925aced0d5e7c118fa7541b3fd6a5cc983
4
+ data.tar.gz: 9a591fdf0b2b481f71cbf871a70b3f83a8cac4bca4c3fe399348dfeee2447a13
5
5
  SHA512:
6
- metadata.gz: 4ace69f14606887e7243a5ec00598d8a3ded4230e8fbdf849c801579f38c9242ca87c5ab48887aeba65911cbcf49e675e768c077d20680e9693c5989180218b7
7
- data.tar.gz: 7986400736b3631524c3427f135a8d3cb9da04da0d1413f59d764fd8c5b7c4ee6f81be9a3b92d848c5546229b7bd7f236278cfe41cb12410c34def542762d1f9
6
+ metadata.gz: 7f5887a701034ac935d6bb1f14a454f6dfe03751ec7842e383f401555f46d021d8bb502658959a5edae9d4199d8e8bfc785721d3386b76f0b6b280c7731fad3d
7
+ data.tar.gz: eb7de74ded26221a86664644ceddda6428e877bdf158acd988319c56bdc335955b506623cc9d8fb3c71376c877d4e00254c018c4341debd221a6439d9557e6ed
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ = 3.67.0 (2023-04-12)
2
+
3
+ * Add custom_block_results plugin for registering custom block result handlers (jeremyevans)
4
+
1
5
  = 3.66.0 (2023-03-13)
2
6
 
3
7
  * Support overriding exception page assets via exception_page_{css,js} instance methods (jeremyevans) (#306)
@@ -0,0 +1,25 @@
1
+ = New Feature
2
+
3
+ * A custom_block_results plugin has been added for custom handling
4
+ of block results. This allows routing blocks to return
5
+ arbitrary objects instead of just String, nil, and false, and
6
+ to have custom handling for them. For example, if you want to
7
+ be able to have your routing blocks return the status code to use,
8
+ you could do:
9
+
10
+ plugin :custom_block_results
11
+
12
+ handle_block_result Integer do |result|
13
+ response.status_code = result
14
+ end
15
+
16
+ route do |r|
17
+ 200
18
+ end
19
+
20
+ While the expected use of the handle_block_result method is with
21
+ class arguments, you can use any argument that implements an
22
+ appropriate === method.
23
+
24
+ The symbol_views and json plugins, which support additional block
25
+ results, now use the custom_block_results plugin internally.
@@ -0,0 +1,68 @@
1
+ # frozen-string-literal: true
2
+
3
+ #
4
+ class Roda
5
+ module RodaPlugins
6
+ # The custom_block_results plugin allows you to specify handling
7
+ # for different block results. By default, Roda only supports
8
+ # nil, false, and string block results, but using this plugin,
9
+ # you can support other block results.
10
+ #
11
+ # For example, if you wanted to support returning Integer
12
+ # block results, and have them set the response status code,
13
+ # you could do:
14
+ #
15
+ # plugin :custom_block_results
16
+ #
17
+ # handle_block_result Integer do |result|
18
+ # response.status_code = result
19
+ # end
20
+ #
21
+ # route do |r|
22
+ # 200
23
+ # end
24
+ #
25
+ # The expected use case for this is to customize behavior by
26
+ # class, but matching uses ===, so it is possible to use non-class
27
+ # objects that respond to === appropriately.
28
+ #
29
+ # Note that custom block result handling only occurs if the types
30
+ # are not handled by Roda itself. You cannot use this to modify
31
+ # the handling of nil, false, or string results.
32
+ module CustomBlockResults
33
+ def self.configure(app)
34
+ app.opts[:custom_block_results] ||= {}
35
+ end
36
+
37
+ module ClassMethods
38
+ # Freeze the configured custom block results when freezing the app.
39
+ def freeze
40
+ opts[:custom_block_results].freeze
41
+ super
42
+ end
43
+
44
+ # Specify a block that will be called when an instance of klass
45
+ # is returned as a block result. The block defines a method.
46
+ def handle_block_result(klass, &block)
47
+ opts[:custom_block_results][klass] = define_roda_method(opts[:custom_block_results][klass] || "custom_block_result_#{klass}", 1, &block)
48
+ end
49
+ end
50
+
51
+ module RequestMethods
52
+ private
53
+
54
+ # Try each configured custom block result, and call the related method
55
+ # to get the block result.
56
+ def unsupported_block_result(result)
57
+ roda_class.opts[:custom_block_results].each do |klass, meth|
58
+ return scope.send(meth, result) if klass === result
59
+ end
60
+
61
+ super
62
+ end
63
+ end
64
+ end
65
+
66
+ register_plugin(:custom_block_results, CustomBlockResults)
67
+ end
68
+ end
@@ -55,11 +55,17 @@ class Roda
55
55
  module Json
56
56
  # Set the classes to automatically convert to JSON, and the serializer to use.
57
57
  def self.configure(app, opts=OPTS)
58
+ app.plugin :custom_block_results
59
+
58
60
  classes = opts[:classes] || [Array, Hash]
59
61
  app.opts[:json_result_classes] ||= []
60
62
  app.opts[:json_result_classes] += classes
61
- app.opts[:json_result_classes].uniq!
62
- app.opts[:json_result_classes].freeze
63
+ classes = app.opts[:json_result_classes]
64
+ classes.uniq!
65
+ classes.freeze
66
+ classes.each do |klass|
67
+ app.opts[:custom_block_results][klass] = :handle_json_block_result
68
+ end
63
69
 
64
70
  app.opts[:json_result_serializer] = opts[:serializer] || app.opts[:json_result_serializer] || app.opts[:json_serializer] || :to_json.to_proc
65
71
 
@@ -71,32 +77,34 @@ class Roda
71
77
  module ClassMethods
72
78
  # The classes that should be automatically converted to json
73
79
  def json_result_classes
80
+ # RODA4: remove, only used by previous implementation.
74
81
  opts[:json_result_classes]
75
82
  end
76
83
  end
77
84
 
85
+ module InstanceMethods
86
+ # Handle a result for one of the registered JSON result classes
87
+ # by converting the result to JSON.
88
+ def handle_json_block_result(result)
89
+ @_response['Content-Type'] ||= opts[:json_result_content_type]
90
+ @_request.send(:convert_to_json, result)
91
+ end
92
+ end
93
+
78
94
  module RequestMethods
79
95
  private
80
96
 
81
- # If the result is an instance of one of the json_result_classes,
82
- # convert the result to json and return it as the body, using the
83
- # application/json content-type.
84
- def block_result_body(result)
85
- case result
86
- when *roda_class.json_result_classes
87
- response['Content-Type'] ||= roda_class.opts[:json_result_content_type]
88
- convert_to_json(result)
89
- else
90
- super
91
- end
92
- end
93
-
94
97
  # Convert the given object to JSON. Uses to_json by default,
95
98
  # but can use a custom serializer passed to the plugin.
96
- def convert_to_json(obj)
97
- args = [obj]
98
- args << self if roda_class.opts[:json_result_include_request]
99
- roda_class.opts[:json_result_serializer].call(*args)
99
+ def convert_to_json(result)
100
+ opts = roda_class.opts
101
+ serializer = opts[:json_result_serializer]
102
+
103
+ if opts[:json_result_include_request]
104
+ serializer.call(result, self)
105
+ else
106
+ serializer.call(result)
107
+ end
100
108
  end
101
109
  end
102
110
  end
@@ -23,18 +23,9 @@ class Roda
23
23
  # :foo
24
24
  # end
25
25
  module SymbolViews
26
- module RequestMethods
27
- private
28
-
29
- # If the block result is a symbol, consider the symbol a
30
- # template name and use the template view as the body.
31
- def block_result_body(result)
32
- if result.is_a?(Symbol)
33
- scope.view(result)
34
- else
35
- super
36
- end
37
- end
26
+ def self.configure(app)
27
+ app.plugin :custom_block_results
28
+ app.opts[:custom_block_results][Symbol] = :view
38
29
  end
39
30
  end
40
31
 
data/lib/roda/request.rb CHANGED
@@ -547,7 +547,7 @@ class Roda
547
547
  when nil, false
548
548
  # nothing
549
549
  else
550
- raise RodaError, "unsupported block result: #{result.inspect}"
550
+ unsupported_block_result(result)
551
551
  end
552
552
  end
553
553
 
@@ -652,6 +652,12 @@ class Roda
652
652
  end
653
653
  end
654
654
 
655
+ # How to handle block results that are not nil, false, or a String.
656
+ # By default raises an exception.
657
+ def unsupported_block_result(result)
658
+ raise RodaError, "unsupported block result: #{result.inspect}"
659
+ end
660
+
655
661
  # Handle an unsupported matcher.
656
662
  def unsupported_matcher(matcher)
657
663
  raise RodaError, "unsupported matcher: #{matcher.inspect}"
data/lib/roda/version.rb CHANGED
@@ -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 = 66
7
+ RodaMinorVersion = 67
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.66.0
4
+ version: 3.67.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: 2023-03-13 00:00:00.000000000 Z
11
+ date: 2023-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -239,6 +239,7 @@ extra_rdoc_files:
239
239
  - doc/release_notes/3.64.0.txt
240
240
  - doc/release_notes/3.65.0.txt
241
241
  - doc/release_notes/3.66.0.txt
242
+ - doc/release_notes/3.67.0.txt
242
243
  - doc/release_notes/3.7.0.txt
243
244
  - doc/release_notes/3.8.0.txt
244
245
  - doc/release_notes/3.9.0.txt
@@ -312,6 +313,7 @@ files:
312
313
  - doc/release_notes/3.64.0.txt
313
314
  - doc/release_notes/3.65.0.txt
314
315
  - doc/release_notes/3.66.0.txt
316
+ - doc/release_notes/3.67.0.txt
315
317
  - doc/release_notes/3.7.0.txt
316
318
  - doc/release_notes/3.8.0.txt
317
319
  - doc/release_notes/3.9.0.txt
@@ -342,6 +344,7 @@ files:
342
344
  - lib/roda/plugins/content_security_policy.rb
343
345
  - lib/roda/plugins/cookies.rb
344
346
  - lib/roda/plugins/csrf.rb
347
+ - lib/roda/plugins/custom_block_results.rb
345
348
  - lib/roda/plugins/custom_matchers.rb
346
349
  - lib/roda/plugins/default_headers.rb
347
350
  - lib/roda/plugins/default_status.rb
@@ -469,7 +472,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
469
472
  - !ruby/object:Gem::Version
470
473
  version: '0'
471
474
  requirements: []
472
- rubygems_version: 3.4.6
475
+ rubygems_version: 3.4.10
473
476
  signing_key:
474
477
  specification_version: 4
475
478
  summary: Routing tree web toolkit