sinatra-wanted 0.8

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2bb6e4a003636fbb934a4b36e249ac757ba1cd450e4d632ea2016b61095d3752
4
+ data.tar.gz: 6493f6270ae54b97c3df03df9b02146b3a40f43c9e8ca667cdd242033da8232a
5
+ SHA512:
6
+ metadata.gz: f9d6e85a50bd7ac41da1160142ddb6932a00527dea08f57204683506a586792e30ac246c08f64e399e6201678a9e035202c7abaff6a1e1153253923bef6403fb
7
+ data.tar.gz: 5453e53c9250895bdf081bca06864a06c2fc06771a28a0a05fcf7457ab8eaaeedad933450d5586790246108050684ad6281febe9b498094bda3162c470a4de27
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ sinatra-wanted
2
+ ==============
3
+
4
+ Parameter processing for Sinatra framework
5
+
6
+ Allow to easily expressing parameter requirements, such as:
7
+
8
+ * required/optional
9
+ * type checking/coercion (best done using dry-types)
10
+ * object retrieval (using Sequel, LOM, or class instantiating)
11
+ * further processing (such as conversion) using block
12
+
13
+ Examples
14
+ ========
15
+
16
+ Note that in URL query `?param` as no value but `?param=` as the
17
+ empty string value (ie: "").
18
+
19
+
20
+ ~~~ruby
21
+ # Retrieve a required VM model from Sequel
22
+ vm = want! :vm, Types::VM::Name, VM
23
+
24
+ # Retrieve a require public key (in rfc4716 or openssh format)
25
+ # and ensure the final result is in openssh format:
26
+ pubkey = want! :pubkey, Types::SSHPublicKey do |k|
27
+ SSHPublicKey.to_openssh(k)
28
+ end
29
+
30
+ # Get an optional parameter called locked which is a boolean,
31
+ # if the parameter is present but as no value use true
32
+ locked = want? :locked, Types::Params::Bool.default(true)
33
+
34
+ # Parameter is optional but in this case we require a default value
35
+ # which will be processed
36
+ type = want :type, Types::VM::Stop, default: 'savestate'
37
+ ~~~
38
+
39
+ Parameter processing
40
+ ====================
41
+ Parameter value retrieval will be processed as follow, please
42
+ read carefully:
43
+
44
+ 1. Retrieve parameter value
45
+ If `param` is a symbol, it's key will be looked up
46
+ in the sinatra parameter list and assign special value:
47
+ * nil : key not found
48
+ * NO_VALUE : key found but no value (ie: nil) associated
49
+
50
+ 2. Check for missing parameter (ie: nil)
51
+ According to named-parameter `missing`:
52
+ * :raise : raise exception WantedMissing
53
+ * :ignore : use the `default` value and continue processing
54
+ * :return : return the `default` value (all processing stops here)
55
+
56
+ 3. Check for missing value (ie: NO_VALUE)
57
+ * If value is missing use instead the value from the
58
+ named parameter `no_value` (default to NO_VALUE)
59
+ * If the type checking/coercion is one of dry-type, the NO_VALUE
60
+ is changed for the Dry::Types::Undefined so that DRY can
61
+ correctly processed undefined value.
62
+
63
+ 4. Perform the type checking / coercion
64
+ This is done by using the first available method: [], call.
65
+
66
+ The easiest (but not required) is to use the dry-types library
67
+
68
+ 5. Unless value is already nil, use a getter to retrieve the real
69
+ value object. Object retrieval will be considered as not found,
70
+ if the getter returns nil
71
+ This is done by using the first available method: [], get,
72
+ fetch, call, new.
73
+
74
+ Usually getter will be Sequel Model, LDAP Object Model,
75
+ Class, ...
76
+
77
+ If not found (ie: nil), according to named-parameter `not_found`:
78
+
79
+ * :raise : raise exception WantedNotFound
80
+ * :ignore : keep the value as nil and continue processing
81
+ * :not_found : execute the sinatra #not_found action
82
+ * :pass : execute the sinatra #pass action
83
+
84
+ 6. Apply block processing
85
+
86
+ \#want, #want!, and #want? are the same methods with different default
87
+ for the `missing` and `not_found` named parameter
88
+
89
+ | method | missing | not_found |
90
+ |--------|---------|------------|
91
+ | want | :ignore | :ignore |
92
+ | want! | :raise | :raise |
93
+ | want? | :return | :ignore |
94
+
@@ -0,0 +1,176 @@
1
+ require_relative 'wanted/version'
2
+
3
+ # {include:file:README.md}
4
+
5
+ module Sinatra::Helpers::Wanted
6
+ # Define a "No Value" object.
7
+ # It is used to signal that a parameter exists but as no associated value.
8
+ NO_VALUE = Object.new.then {|o|
9
+ def o.insect
10
+ "No_Value"
11
+ end
12
+ }.freeze
13
+
14
+ # Generic exception.
15
+ # Only the inherited exceptions are raised.
16
+ class WantedError < StandardError
17
+ def initialize(msg=nil, value: nil, id: nil)
18
+ super(msg)
19
+ @value = value
20
+ @id = id
21
+ end
22
+ end
23
+
24
+ # Exception to notify of syntax error
25
+ class WantedSyntaxError < WantedError
26
+ end
27
+
28
+ # Exception to notify of missing parameter
29
+ class WantedMissing < WantedError
30
+ end
31
+
32
+ # Exception to notify of object not found
33
+ class WantedNotFound < WantedError
34
+ end
35
+
36
+
37
+ # Retrieve value/object associated with a parameter.
38
+ #
39
+ # @param param [Symbol, Object, nil, NO_VALUE] parameter key or parameter value
40
+ # @param type [#[], #call] type checking / coercion
41
+ # @param getter [#[], #get, #fetch, #call, #new] object getter
42
+ # @param id [Symbol] name of the parameter being processed
43
+ # @param default [Object] default value to use if parameter is missing
44
+ # @param no_value [Obejct] default value to use if object is not found
45
+ # @param missing [:raise, :ignore, :return] how to deal with missing parameter
46
+ # @param not_found [:false, :ignore, :not_found, :pass] how to deal with object not found
47
+ #
48
+ # @yieldparam obj [Object] retrieve parameter value/object
49
+ # @yieldreturn [Object] modified value/object
50
+ #
51
+ # @return [Object] parameter value/object
52
+ # @return [nil] parameter is missing or it's value is nil
53
+ # @return [NO_VALUE] parameter has no associated value
54
+ #
55
+ # @raise [WantedMissing] parameter is missing
56
+ # @raise [WantedNotFound] object not found
57
+ # @raise [WantedSyntaxError] syntax error
58
+ #
59
+ def want(param, type=nil, getter=nil, id: nil,
60
+ default: nil, no_value: NO_VALUE,
61
+ missing: :ignore, not_found: :ignore, &block)
62
+ error_handler do
63
+ _want(param, type, getter, id: id,
64
+ default: default, no_value: no_value,
65
+ missing: missing, not_found: not_found, &block)
66
+ end
67
+ end
68
+
69
+ # (see #want)
70
+ def want!(param, type=nil, getter=nil, id: nil,
71
+ default: nil, no_value: NO_VALUE,
72
+ missing: :raise, not_found: :raise, &block)
73
+ want(param, type, getter, id: id,
74
+ default: default, no_value: no_value,
75
+ missing: missing, not_found: not_found, &block)
76
+ end
77
+
78
+ # (see #want)
79
+ def want?(param, type=nil, getter=nil, id: nil,
80
+ default: nil, no_value: NO_VALUE,
81
+ missing: :return, not_found: :ignore, &block)
82
+ want(param, type, getter,
83
+ default: default, id: id, no_value: no_value,
84
+ missing: missing, not_found: not_found, &block)
85
+ end
86
+
87
+
88
+ private
89
+
90
+ def _want(param, type, getter, id:,
91
+ default:, no_value:, missing:, not_found:)
92
+ type_method = if type
93
+ [ :[], :call ]
94
+ .find {|m| type.respond_to?(m) } ||
95
+ raise(ArgumentError)
96
+ end
97
+ get_method = if getter
98
+ [ :[], :get, :fetch, :call, :new ]
99
+ .find {|m| getter.respond_to?(m) } ||
100
+ raise(ArgumentError)
101
+ end
102
+ value, id = if param.kind_of?(Symbol)
103
+ if params.include?(param)
104
+ then [ params[param] || NO_VALUE, param ]
105
+ else [ nil, param ]
106
+ end
107
+ else
108
+ [ param, nil ]
109
+ end
110
+
111
+ # Check for missing param
112
+ # Note: we consider the case where `param` is nil to be
113
+ # a missing parameter, otherwise the user should
114
+ # have explicitly passed NO_VALUE
115
+ if value.nil?
116
+ case missing
117
+ when :raise then raise WantedMissing, id: id
118
+ when :return then return default
119
+ when :ignore then value = default
120
+ else raise ArgumentError
121
+ end
122
+ end
123
+
124
+ # If the parameter has no value, replace it with the
125
+ # user-supplied no_value
126
+ # Note: if type is a dry-type, NO_VALUE will be replaced
127
+ # with Dry::Types::Undefined
128
+ if value == NO_VALUE
129
+ value = no_value
130
+ if value == NO_VALUE &&
131
+ defined?(Dry::Types) && type.kind_of?(Dry::Types::Type)
132
+ value = Dry::Types::Undefined
133
+ end
134
+ end
135
+
136
+ # Build value from various check/conversion
137
+ if type_method
138
+ value = type.public_send(type_method, value)
139
+ end
140
+ if !value.nil? && get_method
141
+ value = getter.public_send(get_method, value)
142
+ # Check if we consider it as not found
143
+ if value.nil?
144
+ case not_found
145
+ when :raise then raise WantedNotFound, id: id
146
+ when :not_found then self.not_found
147
+ when :pass then self.pass
148
+ when :ignore
149
+ else raise ArgumentError
150
+ end
151
+ end
152
+ end
153
+ if block_given?
154
+ value = yield(value)
155
+ end
156
+
157
+ # Return value
158
+ value
159
+ rescue Dry::Types::CoercionError, Dry::Types::ConstraintError
160
+ raise WantedSyntaxError, value: value, id: id
161
+ end
162
+
163
+ def error_handler
164
+ if defined?(Dry::Types)
165
+ begin
166
+ yield
167
+ rescue Dry::Types::CoercionError, Dry::Types::ConstraintError
168
+ raise WantedSyntaxError, value: value, id: id
169
+ end
170
+ else
171
+ yield
172
+ end
173
+ end
174
+
175
+ end
176
+
@@ -0,0 +1,8 @@
1
+ module Sinatra
2
+ module Helpers
3
+ module Wanted
4
+ # Version
5
+ VERSION = 0.8
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'lib/sinatra/helpers/wanted/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'sinatra-wanted'
7
+ s.version = Sinatra::Helpers::Wanted::VERSION
8
+ s.summary = "Parameters processing for Sinatra framework"
9
+ s.description = <<~EOF
10
+ Ease processing of parameters in Sinatra framework.
11
+ Integrates well with dry-types, sequel, ...
12
+
13
+ Example:
14
+ want! :user, Dry::Types::String, User
15
+ want? :expired, Dry::Types::Params::Bool.default(true)
16
+ EOF
17
+
18
+ s.homepage = 'https://gitlab.com/sdalu/sinatra-wanted'
19
+ s.license = 'MIT'
20
+
21
+ s.authors = [ "Stéphane D'Alu" ]
22
+ s.email = [ 'stephane.dalu@insa-lyon.fr' ]
23
+
24
+ s.files = %w[ README.md sinatra-wanted.gemspec ] +
25
+ Dir['lib/**/*.rb']
26
+
27
+ s.add_dependency 'sinatra'
28
+ s.add_development_dependency 'yard', '~>0'
29
+ s.add_development_dependency 'rake', '~>13'
30
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-wanted
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.8'
5
+ platform: ruby
6
+ authors:
7
+ - Stéphane D'Alu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13'
55
+ description: |
56
+ Ease processing of parameters in Sinatra framework.
57
+ Integrates well with dry-types, sequel, ...
58
+
59
+ Example:
60
+ want! :user, Dry::Types::String, User
61
+ want? :expired, Dry::Types::Params::Bool.default(true)
62
+ email:
63
+ - stephane.dalu@insa-lyon.fr
64
+ executables: []
65
+ extensions: []
66
+ extra_rdoc_files: []
67
+ files:
68
+ - README.md
69
+ - lib/sinatra/helpers/wanted.rb
70
+ - lib/sinatra/helpers/wanted/version.rb
71
+ - sinatra-wanted.gemspec
72
+ homepage: https://gitlab.com/sdalu/sinatra-wanted
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.0.8
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Parameters processing for Sinatra framework
95
+ test_files: []