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 +7 -0
- data/README.md +94 -0
- data/lib/sinatra/helpers/wanted.rb +176 -0
- data/lib/sinatra/helpers/wanted/version.rb +8 -0
- data/sinatra-wanted.gemspec +30 -0
- metadata +95 -0
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,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: []
|