roda 3.66.0 → 3.67.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.
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