params_ready 0.0.2 → 0.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 +4 -4
- data/lib/params_ready/builder.rb +21 -0
- data/lib/params_ready/extensions/delegation.rb +1 -0
- data/lib/params_ready/extensions/freezer.rb +2 -0
- data/lib/params_ready/extensions/undefined.rb +8 -0
- data/lib/params_ready/format.rb +4 -2
- data/lib/params_ready/helpers/arel_builder.rb +96 -35
- data/lib/params_ready/helpers/callable.rb +14 -0
- data/lib/params_ready/helpers/interface_definer.rb +48 -0
- data/lib/params_ready/helpers/memo.rb +0 -1
- data/lib/params_ready/helpers/options.rb +77 -9
- data/lib/params_ready/helpers/parameter_storage_class_methods.rb +27 -0
- data/lib/params_ready/helpers/parameter_user_class_methods.rb +18 -14
- data/lib/params_ready/helpers/rule.rb +30 -11
- data/lib/params_ready/helpers/usage_rule.rb +21 -3
- data/lib/params_ready/marshaller/array_marshallers.rb +4 -3
- data/lib/params_ready/marshaller/{hash_set_marshallers.rb → enum_set_marshallers.rb} +5 -5
- data/lib/params_ready/marshaller/polymorph_marshallers.rb +2 -2
- data/lib/params_ready/marshaller/{hash_marshallers.rb → struct_marshallers.rb} +5 -5
- data/lib/params_ready/marshaller/tuple_marshallers.rb +2 -2
- data/lib/params_ready/ordering/column.rb +1 -1
- data/lib/params_ready/output_parameters.rb +13 -2
- data/lib/params_ready/pagination/keyset_pagination.rb +5 -5
- data/lib/params_ready/parameter/{abstract_hash_parameter.rb → abstract_struct_parameter.rb} +6 -6
- data/lib/params_ready/parameter/array_parameter.rb +2 -2
- data/lib/params_ready/parameter/definition.rb +48 -40
- data/lib/params_ready/parameter/{hash_set_parameter.rb → enum_set_parameter.rb} +11 -10
- data/lib/params_ready/parameter/parameter.rb +48 -29
- data/lib/params_ready/parameter/state.rb +4 -4
- data/lib/params_ready/parameter/{hash_parameter.rb → struct_parameter.rb} +11 -10
- data/lib/params_ready/parameter/tuple_parameter.rb +1 -1
- data/lib/params_ready/parameter/value_parameter.rb +14 -10
- data/lib/params_ready/parameter_user.rb +7 -15
- data/lib/params_ready/query/array_grouping.rb +4 -4
- data/lib/params_ready/query/exists_predicate.rb +3 -3
- data/lib/params_ready/query/grouping.rb +8 -2
- data/lib/params_ready/query/join_clause.rb +91 -28
- data/lib/params_ready/query/predicate.rb +3 -3
- data/lib/params_ready/query/relation.rb +29 -14
- data/lib/params_ready/query/structured_grouping.rb +4 -4
- data/lib/params_ready/query/variable_operator_predicate.rb +12 -12
- data/lib/params_ready/value/coder.rb +36 -8
- data/lib/params_ready/version.rb +7 -0
- data/lib/params_ready.rb +3 -11
- metadata +56 -10
@@ -1,9 +1,9 @@
|
|
1
1
|
require_relative 'collection'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'struct_marshallers'
|
3
3
|
|
4
4
|
module ParamsReady
|
5
5
|
module Marshaller
|
6
|
-
class
|
6
|
+
class EnumSetMarshallers
|
7
7
|
module AbstractMarshaller
|
8
8
|
def canonicalize_collection(definition, context, validator, freeze: false)
|
9
9
|
hash = {}
|
@@ -18,7 +18,7 @@ module ParamsReady
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
module
|
21
|
+
module StructMarshaller
|
22
22
|
extend AbstractMarshaller
|
23
23
|
|
24
24
|
def self.canonicalize(definition, hash, context, validator)
|
@@ -30,7 +30,7 @@ module ParamsReady
|
|
30
30
|
|
31
31
|
def self.marshal(parameter, intent)
|
32
32
|
if intent.marshal? parameter.name_for_formatter
|
33
|
-
|
33
|
+
StructMarshallers::StructMarshaller.marshal(parameter, intent)
|
34
34
|
else
|
35
35
|
SetMarshaller.marshal(parameter, intent)
|
36
36
|
end
|
@@ -83,7 +83,7 @@ module ParamsReady
|
|
83
83
|
def self.collection
|
84
84
|
@collection ||= begin
|
85
85
|
c = ClassCollection.new Hash
|
86
|
-
c.add_instance Hash,
|
86
|
+
c.add_instance Hash, StructMarshaller
|
87
87
|
c.add_instance Set, SetMarshaller
|
88
88
|
c.add_instance Array, ArrayMarshaller
|
89
89
|
c.default!(Hash)
|
@@ -3,7 +3,7 @@ require_relative 'collection'
|
|
3
3
|
module ParamsReady
|
4
4
|
module Marshaller
|
5
5
|
class PolymorphMarshallers
|
6
|
-
class
|
6
|
+
class StructMarshaller
|
7
7
|
attr_reader :type_identifier
|
8
8
|
|
9
9
|
def self.instance(type_identifier:)
|
@@ -57,7 +57,7 @@ module ParamsReady
|
|
57
57
|
def self.collection
|
58
58
|
@collection ||= begin
|
59
59
|
c = ClassCollection.new Hash
|
60
|
-
c.add_factory :hash,
|
60
|
+
c.add_factory :hash, StructMarshaller
|
61
61
|
c.freeze
|
62
62
|
c
|
63
63
|
end
|
@@ -4,7 +4,7 @@ require_relative 'collection'
|
|
4
4
|
|
5
5
|
module ParamsReady
|
6
6
|
module Marshaller
|
7
|
-
class
|
7
|
+
class StructMarshallers
|
8
8
|
module AbstractMarshaller
|
9
9
|
def extract_bare_value(parameter, intent)
|
10
10
|
parameter.names.keys.reduce({}) do |result, name|
|
@@ -27,11 +27,11 @@ module ParamsReady
|
|
27
27
|
def self.canonicalize(definition, string, context, validator)
|
28
28
|
json = Base64.urlsafe_decode64(string)
|
29
29
|
hash = JSON.parse(json)
|
30
|
-
|
30
|
+
StructMarshaller.canonicalize(definition, hash, context, validator)
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.marshal(parameter, intent)
|
34
|
-
hash =
|
34
|
+
hash = StructMarshaller.marshal(parameter, intent)
|
35
35
|
json = JSON.generate(hash)
|
36
36
|
Base64.urlsafe_encode64(json)
|
37
37
|
end
|
@@ -39,7 +39,7 @@ module ParamsReady
|
|
39
39
|
freeze
|
40
40
|
end
|
41
41
|
|
42
|
-
module
|
42
|
+
module StructMarshaller
|
43
43
|
extend AbstractMarshaller
|
44
44
|
|
45
45
|
def self.canonicalize(definition, hash, context, validator, freeze: false)
|
@@ -88,7 +88,7 @@ module ParamsReady
|
|
88
88
|
def self.collection
|
89
89
|
@collection ||= begin
|
90
90
|
c = ClassCollection.new Hash
|
91
|
-
c.add_instance Hash,
|
91
|
+
c.add_instance Hash, StructMarshaller
|
92
92
|
c.add_factory :base64, Base64Marshaller
|
93
93
|
c.default!(Hash)
|
94
94
|
c.freeze
|
@@ -43,7 +43,7 @@ module ParamsReady
|
|
43
43
|
freeze
|
44
44
|
end
|
45
45
|
|
46
|
-
module
|
46
|
+
module StructMarshaller
|
47
47
|
extend AbstractMarshaller
|
48
48
|
|
49
49
|
def self.canonicalize(definition, hash, context, validator)
|
@@ -92,7 +92,7 @@ module ParamsReady
|
|
92
92
|
@collection ||= begin
|
93
93
|
c = ClassCollection.new Array
|
94
94
|
c.add_instance Array, ArrayMarshaller
|
95
|
-
c.add_instance Hash,
|
95
|
+
c.add_instance Hash, StructMarshaller
|
96
96
|
c.add_factory :string, StringMarshaller
|
97
97
|
c.freeze
|
98
98
|
c
|
@@ -27,7 +27,7 @@ module ParamsReady
|
|
27
27
|
|
28
28
|
def attribute(name, default_table, context)
|
29
29
|
arel_table = table || default_table
|
30
|
-
arel_builder = Helpers::ArelBuilder.instance(expression(name), arel_table: arel_table)
|
30
|
+
arel_builder = Helpers::ArelBuilder::Attribute.instance(expression(name), arel_table: arel_table)
|
31
31
|
arel_builder.to_arel(arel_table, context, self)
|
32
32
|
end
|
33
33
|
|
@@ -72,6 +72,17 @@ module ParamsReady
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
|
76
|
+
def to_a
|
77
|
+
if @parameter.definition.is_a? Parameter::ArrayParameterDefinition
|
78
|
+
(0...@parameter.length).map do |n|
|
79
|
+
self[n]
|
80
|
+
end
|
81
|
+
else
|
82
|
+
raise ParamsReadyError, "Unimplemented method 'to_a' for #{@parameter.definition.class.name}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
75
86
|
def flat_pairs(format = @intent.format, restriction: @intent.restriction, data: @intent.data)
|
76
87
|
self.class.flatten_hash(for_output(format, restriction: restriction, data: data), scoped_name)
|
77
88
|
end
|
@@ -104,8 +115,8 @@ module ParamsReady
|
|
104
115
|
@parameter.for_frontend(restriction: restriction, data: data)
|
105
116
|
end
|
106
117
|
|
107
|
-
def for_model(restriction: @intent.restriction)
|
108
|
-
@parameter.for_model(restriction: restriction)
|
118
|
+
def for_model(format = :update, restriction: @intent.restriction)
|
119
|
+
@parameter.for_model(format, restriction: restriction)
|
109
120
|
end
|
110
121
|
|
111
122
|
def format(format = @intent)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require_relative '../parameter/
|
1
|
+
require_relative '../parameter/struct_parameter'
|
2
2
|
require_relative '../value/constraint'
|
3
3
|
require_relative '../helpers/arel_builder'
|
4
4
|
require_relative 'abstract_pagination'
|
@@ -6,7 +6,7 @@ require_relative 'direction'
|
|
6
6
|
|
7
7
|
module ParamsReady
|
8
8
|
module Pagination
|
9
|
-
class KeysetPagination < Parameter::
|
9
|
+
class KeysetPagination < Parameter::StructParameter
|
10
10
|
include AbstractPagination
|
11
11
|
|
12
12
|
def select_keysets(query, limit, direction, keyset, ordering, arel_table, context)
|
@@ -177,7 +177,7 @@ module ParamsReady
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
-
class KeysetPaginationDefinition < Parameter::
|
180
|
+
class KeysetPaginationDefinition < Parameter::StructParameterDefinition
|
181
181
|
MIN_LIMIT = 1
|
182
182
|
|
183
183
|
parameter_class KeysetPagination
|
@@ -212,14 +212,14 @@ module ParamsReady
|
|
212
212
|
class KeysetPaginationBuilder
|
213
213
|
def initialize(ordering_builder, default_limit, max_limit = nil)
|
214
214
|
definition = KeysetPaginationDefinition.new(default_limit, max_limit)
|
215
|
-
@cursor_builder = Parameter::
|
215
|
+
@cursor_builder = Parameter::StructParameterBuilder.send :new, definition
|
216
216
|
@default = {
|
217
217
|
limit: default_limit,
|
218
218
|
direction: :aft,
|
219
219
|
keyset: {}
|
220
220
|
}
|
221
221
|
@ordering_builder = ordering_builder
|
222
|
-
@keyset = Parameter::
|
222
|
+
@keyset = Parameter::StructParameterBuilder.instance(:keyset, altn: :ks)
|
223
223
|
end
|
224
224
|
|
225
225
|
def key(type, name, direction, &block)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'parameter'
|
2
2
|
require_relative '../helpers/key_map'
|
3
|
-
require_relative '../marshaller/
|
3
|
+
require_relative '../marshaller/struct_marshallers'
|
4
4
|
require_relative '../marshaller/builder_module'
|
5
5
|
require_relative '../marshaller/definition_module'
|
6
6
|
|
@@ -8,7 +8,7 @@ module ParamsReady
|
|
8
8
|
module Parameter
|
9
9
|
using Extensions::Hash
|
10
10
|
|
11
|
-
class
|
11
|
+
class AbstractStructParameter < Parameter
|
12
12
|
include ComplexParameter
|
13
13
|
|
14
14
|
def_delegators :@definition, :names, :remap?
|
@@ -69,7 +69,7 @@ module ParamsReady
|
|
69
69
|
for_output(format, restriction: restriction, data: data)
|
70
70
|
end
|
71
71
|
|
72
|
-
def for_model(format = :
|
72
|
+
def for_model(format = :update, restriction: nil)
|
73
73
|
for_output(format, restriction: restriction)
|
74
74
|
end
|
75
75
|
|
@@ -132,10 +132,10 @@ module ParamsReady
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
-
module
|
135
|
+
module AbstractStructParameterBuilder
|
136
136
|
include Marshaller::BuilderModule
|
137
137
|
|
138
|
-
module
|
138
|
+
module StructLike
|
139
139
|
def add(input, *args, **opts, &block)
|
140
140
|
definition = self.class.resolve(input, *args, **opts, &block)
|
141
141
|
@definition.add_child definition
|
@@ -143,7 +143,7 @@ module ParamsReady
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
-
class
|
146
|
+
class AbstractStructParameterDefinition < Definition
|
147
147
|
attr_reader :key_map
|
148
148
|
|
149
149
|
def duplicate_value(value)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'parameter'
|
2
2
|
require_relative 'definition'
|
3
|
-
require_relative '
|
3
|
+
require_relative 'abstract_struct_parameter'
|
4
4
|
require_relative '../builder'
|
5
5
|
require_relative '../marshaller/array_marshallers'
|
6
6
|
require_relative '../marshaller/builder_module'
|
@@ -74,7 +74,7 @@ module ParamsReady
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def_delegators :@definition, :prototype
|
77
|
-
def_delegators :bare_value, :length, :each, :each_with_index, :map, :reduce, :to_a
|
77
|
+
def_delegators :bare_value, :length, :count, :each, :each_with_index, :map, :reduce, :to_a
|
78
78
|
|
79
79
|
freeze_variable :value do |array|
|
80
80
|
array.each(&:freeze)
|
@@ -9,6 +9,7 @@ require_relative '../extensions/undefined'
|
|
9
9
|
require_relative '../input_context'
|
10
10
|
require_relative '../result'
|
11
11
|
require_relative '../helpers/conditional_block'
|
12
|
+
require_relative '../helpers/callable'
|
12
13
|
|
13
14
|
module ParamsReady
|
14
15
|
module Parameter
|
@@ -96,7 +97,7 @@ module ParamsReady
|
|
96
97
|
preprocessor: nil,
|
97
98
|
populator: nil,
|
98
99
|
postprocessor: nil,
|
99
|
-
|
100
|
+
no_input: nil,
|
100
101
|
no_output: nil,
|
101
102
|
**opts
|
102
103
|
)
|
@@ -106,7 +107,7 @@ module ParamsReady
|
|
106
107
|
@preprocessor = preprocessor
|
107
108
|
@postprocessor = postprocessor
|
108
109
|
@populator = populator
|
109
|
-
@
|
110
|
+
@no_input = no_input
|
110
111
|
@no_output = no_output
|
111
112
|
|
112
113
|
set_default(default) unless default == Extensions::Undefined
|
@@ -126,6 +127,7 @@ module ParamsReady
|
|
126
127
|
end
|
127
128
|
|
128
129
|
late_init :populator, getter: true, once: true, obligatory: false
|
130
|
+
late_init :no_input, getter: false, once: false
|
129
131
|
late_init :no_output, getter: false, once: false
|
130
132
|
late_init :memoize, getter: true, obligatory: false
|
131
133
|
|
@@ -173,52 +175,45 @@ module ParamsReady
|
|
173
175
|
validator
|
174
176
|
end
|
175
177
|
|
176
|
-
def
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
@local = Helpers::Rule(rule)
|
181
|
-
end
|
178
|
+
def set_no_input(*arr, rule: nil)
|
179
|
+
@no_input = Helpers::Rule(rule) || true
|
180
|
+
raise ParamsReadyError, "Default not expected: #{arr}" if rule == false
|
181
|
+
|
182
182
|
set_default *arr unless arr.empty?
|
183
183
|
end
|
184
184
|
|
185
|
-
def
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
else
|
194
|
-
raise ParamsReadyError, "Unexpected rule: #{@local}"
|
195
|
-
end
|
185
|
+
def set_local(*arr, rule: nil)
|
186
|
+
rule = Helpers::Rule(rule)
|
187
|
+
set_no_input(*arr, rule: rule)
|
188
|
+
set_no_output(rule || true)
|
189
|
+
end
|
190
|
+
|
191
|
+
def no_input?(format)
|
192
|
+
restricted_for_format?(@no_input, format)
|
196
193
|
end
|
197
194
|
|
198
195
|
def no_output?(format)
|
199
|
-
|
196
|
+
restricted_for_format?(@no_output, format)
|
197
|
+
end
|
198
|
+
|
199
|
+
def restricted_for_format?(rule, format)
|
200
|
+
case rule
|
200
201
|
when nil, false
|
201
|
-
|
202
|
+
false
|
202
203
|
when true
|
203
|
-
|
204
|
+
!format.local?
|
204
205
|
when Helpers::Rule
|
205
|
-
|
206
|
+
rule.include?(format.name)
|
206
207
|
else
|
207
|
-
raise ParamsReadyError, "Unexpected
|
208
|
+
raise ParamsReadyError, "Unexpected rule: #{rule}"
|
208
209
|
end
|
209
210
|
end
|
210
211
|
|
211
|
-
late_init :optional, boolean: true, getter: false, once: false
|
212
|
-
next value if value == false
|
213
|
-
raise ParamsReadyError, "Optional parameter can't have default" if default_defined?
|
214
|
-
|
215
|
-
value
|
216
|
-
end
|
212
|
+
late_init :optional, boolean: true, getter: false, once: false
|
217
213
|
|
218
214
|
late_init :default, once: false, definite: false do |value|
|
219
215
|
next value if value == Extensions::Undefined
|
220
|
-
|
221
|
-
raise ParamsReadyError, "Optional parameter can't have default" if optional?
|
216
|
+
next value if value.is_a? Helpers::Callable
|
222
217
|
|
223
218
|
canonical = canonical_default(value)
|
224
219
|
next canonical if canonical.nil?
|
@@ -226,25 +221,38 @@ module ParamsReady
|
|
226
221
|
freeze_value(canonical)
|
227
222
|
end
|
228
223
|
|
229
|
-
def
|
224
|
+
def fetch_default(duplicate: true)
|
230
225
|
return Extensions::Undefined unless default_defined?
|
231
226
|
return nil if @default.nil?
|
232
227
|
|
233
|
-
|
228
|
+
if @default.is_a?(Helpers::Callable)
|
229
|
+
fetch_callable_default
|
230
|
+
else
|
231
|
+
return @default unless duplicate
|
232
|
+
duplicate_value(@default)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def fetch_callable_default
|
237
|
+
value = @default.call
|
238
|
+
value = ensure_canonical(value)
|
239
|
+
duplicate_value(value)
|
240
|
+
rescue StandardError => e
|
241
|
+
raise ParamsReadyError, "Invalid default: #{e.message}"
|
234
242
|
end
|
235
243
|
|
236
244
|
|
237
245
|
def finish
|
238
|
-
if @populator && !@
|
239
|
-
raise ParamsReadyError, "Populator set for
|
246
|
+
if @populator && !@no_input
|
247
|
+
raise ParamsReadyError, "Populator set for input parameter '#{name}'"
|
240
248
|
end
|
241
249
|
|
242
|
-
if @preprocessor && @
|
243
|
-
raise ParamsReadyError, "Preprocessor set for
|
250
|
+
if @preprocessor && @no_input == true
|
251
|
+
raise ParamsReadyError, "Preprocessor set for no-input parameter '#{name}'"
|
244
252
|
end
|
245
253
|
|
246
|
-
if @postprocessor && @
|
247
|
-
raise ParamsReadyError, "Postprocessor set for
|
254
|
+
if @postprocessor && @no_input == true
|
255
|
+
raise ParamsReadyError, "Postprocessor set for no-input parameter '#{name}'"
|
248
256
|
end
|
249
257
|
|
250
258
|
super
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'set'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'struct_parameter'
|
3
3
|
require_relative 'value_parameter'
|
4
4
|
require_relative '../intent'
|
5
|
-
require_relative '../marshaller/
|
5
|
+
require_relative '../marshaller/enum_set_marshallers'
|
6
6
|
require_relative '../marshaller/parameter_module'
|
7
7
|
|
8
8
|
module ParamsReady
|
9
9
|
module Parameter
|
10
|
-
class
|
10
|
+
class EnumSetParameter < AbstractStructParameter
|
11
11
|
include Marshaller::ParameterModule
|
12
12
|
|
13
13
|
def self.intent_for_set(intent)
|
@@ -31,13 +31,14 @@ module ParamsReady
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
class
|
34
|
+
class EnumSetParameterBuilder < Builder
|
35
35
|
include Marshaller::BuilderModule
|
36
36
|
|
37
|
-
register :
|
37
|
+
register :enum_set
|
38
|
+
register_deprecated :hash_set, use: :enum_set
|
38
39
|
|
39
40
|
def self.instance(name, altn: nil, type: :boolean)
|
40
|
-
new
|
41
|
+
new EnumSetParameterDefinition.new(name, altn: altn, type: type)
|
41
42
|
end
|
42
43
|
|
43
44
|
def add(input, *args, val: nil, **opts, &block)
|
@@ -56,12 +57,12 @@ module ParamsReady
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
59
|
-
class
|
60
|
+
class EnumSetParameterDefinition < AbstractStructParameterDefinition
|
60
61
|
attr_reader :type, :values
|
61
62
|
freeze_variable :values
|
62
|
-
name_for_formatter :
|
63
|
-
parameter_class
|
64
|
-
include Marshaller::DefinitionModule[Marshaller::
|
63
|
+
name_for_formatter :enum_set
|
64
|
+
parameter_class EnumSetParameter
|
65
|
+
include Marshaller::DefinitionModule[Marshaller::EnumSetMarshallers.collection]
|
65
66
|
|
66
67
|
def initialize(*args, type: :boolean, **opts)
|
67
68
|
@type = type
|
@@ -8,8 +8,12 @@ module ParamsReady
|
|
8
8
|
module Parameter
|
9
9
|
module FromHash
|
10
10
|
def set_from_hash(hash, context: nil, validator: Result.new(name))
|
11
|
-
|
12
|
-
|
11
|
+
if no_input?(context)
|
12
|
+
populate(context, validator)
|
13
|
+
else
|
14
|
+
_, input = find_in_hash hash, context
|
15
|
+
set_from_input(input, context, validator)
|
16
|
+
end
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
@@ -184,7 +188,9 @@ module ParamsReady
|
|
184
188
|
end
|
185
189
|
|
186
190
|
def inspect
|
187
|
-
|
191
|
+
preserve = Format.instance(:inspect).preserve?(self)
|
192
|
+
content = preserve ? inspect_content : '[FILTERED]'
|
193
|
+
"#{self.class.name.split("::").last} #{self.name}: { #{content} }"
|
188
194
|
end
|
189
195
|
|
190
196
|
def dup
|
@@ -205,7 +211,7 @@ module ParamsReady
|
|
205
211
|
|
206
212
|
class Parameter < AbstractParameter
|
207
213
|
def_delegators :@definition,
|
208
|
-
:default, :optional?, :default_defined?, :constraints, :no_output?, :
|
214
|
+
:default, :optional?, :default_defined?, :constraints, :no_output?, :no_input?
|
209
215
|
|
210
216
|
def initialize(definition)
|
211
217
|
@value = Extensions::Undefined
|
@@ -248,6 +254,7 @@ module ParamsReady
|
|
248
254
|
|
249
255
|
def is_definite?
|
250
256
|
return true if @value != Extensions::Undefined && !@value.nil?
|
257
|
+
return false if optional? && @value.nil?
|
251
258
|
|
252
259
|
definite_default?
|
253
260
|
end
|
@@ -267,7 +274,13 @@ module ParamsReady
|
|
267
274
|
end
|
268
275
|
|
269
276
|
def is_undefined?
|
270
|
-
@value == Extensions::Undefined &&
|
277
|
+
@value == Extensions::Undefined && allows_undefined?
|
278
|
+
end
|
279
|
+
|
280
|
+
def allows_undefined?
|
281
|
+
return true if optional?
|
282
|
+
|
283
|
+
!default_defined?
|
271
284
|
end
|
272
285
|
|
273
286
|
def eligible_for_output?(intent)
|
@@ -278,14 +291,6 @@ module ParamsReady
|
|
278
291
|
format.hash_key(self)
|
279
292
|
end
|
280
293
|
|
281
|
-
def set_from_hash(hash, context: nil, validator: Result.new(name))
|
282
|
-
if local?(context)
|
283
|
-
populate(context, validator)
|
284
|
-
else
|
285
|
-
super
|
286
|
-
end
|
287
|
-
end
|
288
|
-
|
289
294
|
def set_from_input(input, context, validator)
|
290
295
|
preprocessed = definition.preprocess(input, context, validator)
|
291
296
|
set_value preprocessed, context, validator
|
@@ -342,14 +347,18 @@ module ParamsReady
|
|
342
347
|
format(Intent.instance(:backend))
|
343
348
|
end
|
344
349
|
|
345
|
-
def unwrap_or(
|
350
|
+
def unwrap_or(*args, &block)
|
351
|
+
ensure_default_present!(*args, &block)
|
352
|
+
|
346
353
|
if is_definite?
|
347
|
-
|
354
|
+
begin
|
355
|
+
unwrap
|
356
|
+
rescue StandardError => _
|
357
|
+
supply_default(*args, &block)
|
358
|
+
end
|
348
359
|
else
|
349
|
-
|
360
|
+
supply_default(*args, &block)
|
350
361
|
end
|
351
|
-
rescue StandardError => _
|
352
|
-
default
|
353
362
|
end
|
354
363
|
|
355
364
|
def find_in_hash(hash, context)
|
@@ -389,17 +398,17 @@ module ParamsReady
|
|
389
398
|
|
390
399
|
def handle_indefinite_input(input, validator)
|
391
400
|
value_missing validator
|
392
|
-
if
|
401
|
+
if default_defined?
|
393
402
|
# if value_missing doesn't crash,
|
394
403
|
# and the parameter is optional
|
395
404
|
# it's safe to set to nil or Extensions::Undefined
|
396
|
-
@value =
|
397
|
-
elsif
|
405
|
+
@value = Extensions::Undefined
|
406
|
+
elsif optional?
|
398
407
|
# Clear possible previous state,
|
399
408
|
# will be set to default on read
|
400
|
-
@value =
|
409
|
+
@value = input
|
401
410
|
else
|
402
|
-
raise ParamsReadyError, "Unexpected state in #handle_indefinite_input" if validator.ok?
|
411
|
+
raise ParamsReadyError, "Unexpected state for '#{name}' in #handle_indefinite_input" if validator.ok?
|
403
412
|
end
|
404
413
|
end
|
405
414
|
|
@@ -427,22 +436,32 @@ module ParamsReady
|
|
427
436
|
nil
|
428
437
|
end
|
429
438
|
|
439
|
+
def ensure_default_present!(*args, &block)
|
440
|
+
raise ParamsReadyError, 'Single default value expected' if args.length > 1
|
441
|
+
raise ParamsReadyError, 'Supply either default or a block' if args.length == 0 && block.nil?
|
442
|
+
warn 'WARNING: block supersedes default value' if args.length > 0 && block
|
443
|
+
end
|
444
|
+
|
445
|
+
def supply_default(*args, &block)
|
446
|
+
if block.nil?
|
447
|
+
args[0]
|
448
|
+
else
|
449
|
+
block.call
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
430
453
|
def init_for_read(to_be_frozen = false)
|
431
454
|
return unless @value == Extensions::Undefined
|
432
455
|
return unless default_defined?
|
433
456
|
|
434
|
-
@value =
|
435
|
-
definition.default
|
436
|
-
else
|
437
|
-
definition.duplicate_default
|
438
|
-
end
|
457
|
+
@value = definition.fetch_default(duplicate: !to_be_frozen)
|
439
458
|
end
|
440
459
|
|
441
460
|
def init_for_write
|
442
461
|
return if is_definite?
|
443
462
|
|
444
463
|
if default_defined? && !default.nil?
|
445
|
-
@value = definition.
|
464
|
+
@value = definition.fetch_default
|
446
465
|
else
|
447
466
|
init_value
|
448
467
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require_relative '../error'
|
2
|
-
require_relative '../../params_ready/parameter/
|
2
|
+
require_relative '../../params_ready/parameter/struct_parameter'
|
3
3
|
require_relative '../query/relation'
|
4
4
|
|
5
5
|
module ParamsReady
|
6
6
|
module Parameter
|
7
|
-
class State <
|
7
|
+
class State < StructParameter
|
8
8
|
extend Query::Relation::PageAccessors
|
9
9
|
extend Forwardable
|
10
10
|
def_delegators :definition, :relations
|
@@ -98,7 +98,7 @@ module ParamsReady
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
class StateBuilder <
|
101
|
+
class StateBuilder < StructParameterBuilder
|
102
102
|
def relation(relation)
|
103
103
|
@definition.add_relation relation
|
104
104
|
end
|
@@ -109,7 +109,7 @@ module ParamsReady
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
-
class StateDefinition <
|
112
|
+
class StateDefinition < StructParameterDefinition
|
113
113
|
parameter_class State
|
114
114
|
attr_reader :relations
|
115
115
|
|