params_ready 0.0.2 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f153e27fbce45bc4e81a566ef856825db2dea6a144e2122202728e6f937e7b9f
|
4
|
+
data.tar.gz: 1d5c56bcc909fa607022cb1f236a91ab4707dbf6753cd4f8ed1d1702a80be997
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8f822219c2fa60a422bf9afb4d483e882eb61aa25a16491534feadf351c8eae8648576e3efcd9bc4e45889701946d8c48a1b5870b440d8e2eb2692cb9368c9a
|
7
|
+
data.tar.gz: 93ce29aafd6b755cc9a628f8ee7ff58c4d2b7c8f5f0b9dede9a75f8fb67e1255dd6e89ae9890ab61ef3737dcdf1d4d9c847dcab9ddd371250ed71a729f135e39
|
data/lib/params_ready/builder.rb
CHANGED
@@ -28,6 +28,23 @@ module ParamsReady
|
|
28
28
|
register_builder(name, self)
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.register_deprecated(name, use:)
|
32
|
+
raise ParamsReadyError, 'Recommended replacement must not be nil' if use.nil?
|
33
|
+
@deprecated ||= {}
|
34
|
+
@deprecated[name] = use.to_s.freeze
|
35
|
+
register_builder(name, self)
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
alias_method :fetch_builder, :builder
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.builder(name)
|
43
|
+
use = @deprecated[name] if @deprecated&.key? name
|
44
|
+
warn "Builder name deprecated: #{name}, use: #{use}" unless use.nil?
|
45
|
+
fetch_builder(name)
|
46
|
+
end
|
47
|
+
|
31
48
|
def self.define_parameter(type, *args, **opts, &block)
|
32
49
|
builder_class = builder(type)
|
33
50
|
builder = builder_class.instance(*args, **opts)
|
@@ -94,6 +111,10 @@ module ParamsReady
|
|
94
111
|
@definition.set_no_output Helpers::Rule(rule) || true
|
95
112
|
end
|
96
113
|
|
114
|
+
def no_input(*arr, rule: nil)
|
115
|
+
@definition.set_no_input *arr, rule: rule
|
116
|
+
end
|
117
|
+
|
97
118
|
def local(*arr, rule: nil)
|
98
119
|
@definition.set_local *arr, rule: rule
|
99
120
|
end
|
@@ -25,6 +25,8 @@ module ParamsReady
|
|
25
25
|
next if frozen?
|
26
26
|
self.class.variables_to_freeze.each do |(ivar, block)|
|
27
27
|
variable = instance_variable_get ivar
|
28
|
+
next if Extensions::Undefined.value_indefinite?(variable)
|
29
|
+
|
28
30
|
block.call(variable) unless block.nil?
|
29
31
|
variable.freeze
|
30
32
|
end
|
data/lib/params_ready/format.rb
CHANGED
@@ -100,8 +100,10 @@ module ParamsReady
|
|
100
100
|
@names = {
|
101
101
|
backend: Format.new(marshal: :none, omit: [], naming_scheme: :standard, remap: false, local: true, name: :backend),
|
102
102
|
frontend: Format.new(marshal: :all, omit: OMIT_ALL, naming_scheme: :alternative, remap: false, local: false, name: :frontend),
|
103
|
-
|
104
|
-
|
103
|
+
create: Format.new(marshal: :none, omit: [], naming_scheme: :standard, remap: false, local: true, name: :create),
|
104
|
+
update: Format.new(marshal: :none, omit: %i(undefined), naming_scheme: :standard, remap: false, local: true, name: :update),
|
105
|
+
json: Format.new(marshal: { except: [:array, :tuple, :boolean, :number] }, omit: [], naming_scheme: :alternative, remap: true, local: false, name: :json),
|
106
|
+
inspect: Format.new(marshal: :none, omit: [], naming_scheme: :standard, remap: false, local: false, name: :inspect)
|
105
107
|
}.freeze
|
106
108
|
|
107
109
|
def self.define(name, format)
|
@@ -2,26 +2,7 @@ require_relative '../error'
|
|
2
2
|
|
3
3
|
module ParamsReady
|
4
4
|
module Helpers
|
5
|
-
|
6
|
-
def self.instance(object, arel_table: nil)
|
7
|
-
case object
|
8
|
-
when Arel::Nodes::Node, Arel::Nodes::SqlLiteral, Arel::Attribute
|
9
|
-
raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
|
10
|
-
ArelObject.new(object)
|
11
|
-
when Proc
|
12
|
-
raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
|
13
|
-
Callable.new(object)
|
14
|
-
when String, Symbol
|
15
|
-
Literal.new(object, arel_table)
|
16
|
-
else
|
17
|
-
raise ParamsReadyError, "Unexpected type for arel builder: #{object.class.name}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.safe_name(name)
|
22
|
-
name[0...64]
|
23
|
-
end
|
24
|
-
|
5
|
+
module ArelBuilder
|
25
6
|
class Callable
|
26
7
|
def initialize(proc)
|
27
8
|
@proc = proc
|
@@ -31,38 +12,118 @@ module ParamsReady
|
|
31
12
|
result = @proc.call(*args)
|
32
13
|
case result
|
33
14
|
when String, Symbol
|
34
|
-
|
15
|
+
to_literal(result).to_arel(*args)
|
35
16
|
else
|
36
17
|
result
|
37
18
|
end
|
38
19
|
end
|
20
|
+
|
21
|
+
def to_literal(*)
|
22
|
+
raise ParamsReadyError, "Unimplemented: #{self.class.name}##{__callee__}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class ArelObject
|
27
|
+
def initialize(node)
|
28
|
+
@node = node
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_arel(*)
|
32
|
+
@node
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.safe_name(name)
|
37
|
+
name[0...64]
|
39
38
|
end
|
40
39
|
|
41
40
|
class Literal
|
42
|
-
def initialize(literal
|
43
|
-
@literal = literal.to_s
|
44
|
-
@arel_table = arel_table
|
41
|
+
def initialize(literal)
|
42
|
+
@literal = literal.to_s.freeze
|
45
43
|
end
|
46
44
|
|
47
|
-
def to_arel(
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
def to_arel(*)
|
46
|
+
Arel::Nodes::SqlLiteral.new(@literal)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Attribute
|
51
|
+
def self.instance(object, arel_table: nil)
|
52
|
+
case object
|
53
|
+
when Arel::Nodes::Node, Arel::Nodes::SqlLiteral, Arel::Attribute
|
54
|
+
raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
|
55
|
+
ArelObject.new(object)
|
56
|
+
when Proc
|
57
|
+
raise ParamsReadyError, "Arel table unexpected" unless arel_table.nil? || arel_table == :none
|
58
|
+
Callable.new(object)
|
59
|
+
when String, Symbol
|
60
|
+
Literal.new(object, arel_table)
|
51
61
|
else
|
52
|
-
|
62
|
+
raise ParamsReadyError, "Unexpected type for arel builder: #{object.class.name}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Callable < ArelBuilder::Callable
|
67
|
+
def to_literal(string)
|
68
|
+
Helpers::ArelBuilder::Attribute.instance(string)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Literal < ArelBuilder::Literal
|
73
|
+
def initialize(literal, arel_table)
|
74
|
+
super literal
|
75
|
+
@arel_table = arel_table
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_arel(default_table, *args)
|
79
|
+
arel_table = @arel_table || default_table
|
80
|
+
if arel_table == :none
|
81
|
+
super(*args)
|
82
|
+
else
|
83
|
+
arel_table[@literal]
|
84
|
+
end
|
53
85
|
end
|
54
86
|
end
|
55
87
|
end
|
56
88
|
|
57
|
-
class
|
58
|
-
def
|
59
|
-
|
89
|
+
class Table
|
90
|
+
def self.instance(object, table_alias: nil)
|
91
|
+
case object
|
92
|
+
when Arel::Table, Arel::Nodes::TableAlias
|
93
|
+
raise ParamsReadyError, "Table alias unexpected" unless table_alias.nil?
|
94
|
+
ArelObject.new(object)
|
95
|
+
when Proc
|
96
|
+
Callable.new(object, table_alias)
|
97
|
+
when String, Symbol
|
98
|
+
Literal.new(object, table_alias)
|
99
|
+
else
|
100
|
+
raise ParamsReadyError, "Unexpected type for arel builder: #{object.class.name}"
|
101
|
+
end
|
60
102
|
end
|
61
103
|
|
62
|
-
|
63
|
-
|
104
|
+
class Callable < ArelBuilder::Callable
|
105
|
+
def initialize(proc, table_alias)
|
106
|
+
super proc
|
107
|
+
@table_alias = table_alias
|
108
|
+
end
|
109
|
+
|
110
|
+
def to_literal(string)
|
111
|
+
Helpers::ArelBuilder::Table.instance(string, table_alias: @table_alias)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class Literal < ArelBuilder::Literal
|
116
|
+
def initialize(literal, table_alias)
|
117
|
+
super literal
|
118
|
+
raise "Table alias must be present" if table_alias.nil?
|
119
|
+
@table_alias = table_alias.to_s.freeze
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_arel(*)
|
123
|
+
Arel::Table.new(@literal).as(@table_alias)
|
124
|
+
end
|
64
125
|
end
|
65
126
|
end
|
66
127
|
end
|
67
128
|
end
|
68
|
-
end
|
129
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ParamsReady
|
2
|
+
module Helpers
|
3
|
+
class InterfaceDefiner
|
4
|
+
def initialize(action_names, user)
|
5
|
+
@action_names = action_names
|
6
|
+
@user = user
|
7
|
+
end
|
8
|
+
|
9
|
+
def parameters(*names)
|
10
|
+
names.each do |name|
|
11
|
+
parameter(name)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def relations(*names)
|
16
|
+
names.each do |name|
|
17
|
+
relation(name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parameter(name)
|
22
|
+
@user.use_parameter(name, only: @action_names)
|
23
|
+
end
|
24
|
+
|
25
|
+
def relation(name)
|
26
|
+
@user.use_relation(name, only: @action_names)
|
27
|
+
end
|
28
|
+
|
29
|
+
def define(parameter: nil, relation: nil, parameters: [], relations: [], &block)
|
30
|
+
parameters = self.class.complete_list(parameter, parameters)
|
31
|
+
parameters(*parameters)
|
32
|
+
relations = self.class.complete_list(relation, relations)
|
33
|
+
relations(*relations)
|
34
|
+
instance_eval(&block) unless block.nil?
|
35
|
+
@option
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.complete_list(singular, plural)
|
39
|
+
list = singular.nil? ? plural : [singular, *plural]
|
40
|
+
normalize_list(list)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.normalize_list(list)
|
44
|
+
list.map(&:to_sym)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -3,37 +3,105 @@ require_relative 'usage_rule'
|
|
3
3
|
|
4
4
|
module ParamsReady
|
5
5
|
module Helpers
|
6
|
-
class Options
|
6
|
+
class Options
|
7
7
|
attr_reader :parameters, :relations
|
8
8
|
|
9
9
|
def initialize
|
10
|
-
super
|
11
10
|
@parameter_rules = Hash.new
|
12
11
|
@relation_rules = Hash.new
|
13
|
-
@
|
12
|
+
@memo = { definitions: {} }
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset_memo!(*args)
|
16
|
+
args.each do |key|
|
17
|
+
@memo[key].clear
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def dup
|
22
|
+
duplicate = Options.new
|
23
|
+
@parameter_rules.each do |_, rule|
|
24
|
+
duplicate.merge_parameter_rule(rule)
|
25
|
+
end
|
26
|
+
@relation_rules.each do |_, rule|
|
27
|
+
duplicate.merge_relation_rule(rule)
|
28
|
+
end
|
29
|
+
duplicate
|
30
|
+
end
|
31
|
+
|
32
|
+
def relation_definitions_for(name)
|
33
|
+
definitions_for(name, relation_rules)
|
34
|
+
end
|
35
|
+
|
36
|
+
def parameter_definitions_for(name)
|
37
|
+
definitions_for(name, parameter_rules)
|
38
|
+
end
|
39
|
+
|
40
|
+
def definitions_for(name, rules)
|
41
|
+
rules.each_with_object([]) do |(_, rule), result|
|
42
|
+
next unless rule.valid_for?(name)
|
43
|
+
|
44
|
+
result << rule.parameter_definition
|
45
|
+
end
|
14
46
|
end
|
15
47
|
|
16
48
|
def use_parameter(param, rule_args = :all)
|
17
49
|
rule = UsageRule.new(param, rule_args)
|
18
|
-
|
50
|
+
merge_parameter_rule(rule)
|
51
|
+
end
|
52
|
+
|
53
|
+
def merge_parameter_rule(rule)
|
54
|
+
reset_memo!(:definitions)
|
55
|
+
@parameter_rules = self.class.merge_rule(rule, @parameter_rules)
|
19
56
|
end
|
20
57
|
|
21
58
|
def use_relation(relation, rule_args = :all)
|
22
59
|
rule = UsageRule.new(relation, rule_args)
|
23
|
-
|
60
|
+
merge_relation_rule(rule)
|
61
|
+
end
|
62
|
+
|
63
|
+
def merge_relation_rule(rule)
|
64
|
+
reset_memo!(:definitions)
|
65
|
+
@relation_rules = self.class.merge_rule(rule, @relation_rules)
|
24
66
|
end
|
25
67
|
|
26
68
|
def parameter_rules
|
27
|
-
|
28
|
-
|
69
|
+
if block_given?
|
70
|
+
@parameter_rules.each_value do |rule|
|
71
|
+
yield rule
|
72
|
+
end
|
29
73
|
end
|
74
|
+
@parameter_rules
|
30
75
|
end
|
31
76
|
|
32
77
|
def relation_rules
|
33
|
-
|
34
|
-
|
78
|
+
if block_given?
|
79
|
+
@relation_rules.each_value do |rule|
|
80
|
+
yield rule
|
81
|
+
end
|
82
|
+
end
|
83
|
+
@relation_rules
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_state_for(key)
|
87
|
+
@memo[:definitions][key] ||= begin
|
88
|
+
builder = Parameter::StateBuilder.instance
|
89
|
+
parameter_definitions_for(key).each do |definition|
|
90
|
+
builder.add definition
|
91
|
+
end
|
92
|
+
relation_definitions_for(key).each do |definition|
|
93
|
+
builder.relation definition
|
94
|
+
end
|
95
|
+
builder.build
|
35
96
|
end
|
36
97
|
end
|
98
|
+
|
99
|
+
def self.merge_rule(rule, rules)
|
100
|
+
existing = rules[rule.name]
|
101
|
+
merged = rule.merge(existing)
|
102
|
+
rules[rule.name] = merged
|
103
|
+
rules
|
104
|
+
end
|
37
105
|
end
|
38
106
|
end
|
39
107
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'storage'
|
2
2
|
require_relative '../error'
|
3
|
+
require_relative 'rule'
|
3
4
|
|
4
5
|
module ParamsReady
|
5
6
|
module Helpers
|
@@ -31,6 +32,32 @@ module ParamsReady
|
|
31
32
|
raise ParamsReadyError, "Unknown parameter '#{sym_key}'"
|
32
33
|
end
|
33
34
|
end
|
35
|
+
|
36
|
+
def include_parameters(parameter_definer, rule = nil)
|
37
|
+
rule = Helpers::Rule(rule)
|
38
|
+
parameter_definer.all_parameters.each do |key, definition|
|
39
|
+
next if rule && !rule.include?(key)
|
40
|
+
|
41
|
+
add_parameter(definition)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def add_parameter(definition)
|
46
|
+
params_ready_storage.add_parameter(definition)
|
47
|
+
end
|
48
|
+
|
49
|
+
def include_relations(parameter_definer, rule = nil)
|
50
|
+
rule = Helpers::Rule(rule)
|
51
|
+
parameter_definer.all_relations.each do |key, definition|
|
52
|
+
next if rule && !rule.include?(key)
|
53
|
+
|
54
|
+
add_relation(definition)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_relation(definition)
|
59
|
+
params_ready_storage.add_relation(definition)
|
60
|
+
end
|
34
61
|
end
|
35
62
|
end
|
36
63
|
end
|
@@ -1,31 +1,35 @@
|
|
1
|
+
require_relative 'interface_definer'
|
2
|
+
|
1
3
|
module ParamsReady
|
2
4
|
module Helpers
|
3
5
|
module ParameterUserClassMethods
|
4
|
-
def
|
5
|
-
@
|
6
|
+
def params_ready_option
|
7
|
+
@params_ready_option ||= begin
|
8
|
+
if superclass.respond_to? :params_ready_option
|
9
|
+
# This works on assumption that superclass
|
10
|
+
# definition doesn't change during execution
|
11
|
+
superclass.params_ready_option.dup
|
12
|
+
else
|
13
|
+
ParamsReady::Helpers::Options.new
|
14
|
+
end
|
15
|
+
end
|
6
16
|
end
|
7
17
|
|
8
18
|
def use_parameter(name, rule = :all)
|
9
19
|
parameter = parameter_definition name
|
10
|
-
|
20
|
+
params_ready_option.use_parameter parameter, rule
|
11
21
|
end
|
12
22
|
|
13
23
|
def use_relation(name, rule = :all)
|
14
24
|
relation = relation_definition name
|
15
|
-
|
25
|
+
params_ready_option.use_relation relation, rule
|
16
26
|
end
|
17
27
|
|
18
|
-
def
|
19
|
-
|
20
|
-
params_ready_storage.add_parameter(p)
|
21
|
-
end
|
22
|
-
end
|
28
|
+
def action_interface(*action_names, **opts, &block)
|
29
|
+
definer = InterfaceDefiner.new(action_names, self)
|
23
30
|
|
24
|
-
|
25
|
-
parameter_definer.all_relations.values.each do |d|
|
26
|
-
params_ready_storage.add_relation(d)
|
27
|
-
end
|
31
|
+
definer.define(**opts, &block)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
end
|
31
|
-
end
|
35
|
+
end
|
@@ -6,33 +6,52 @@ module ParamsReady
|
|
6
6
|
return input if input.nil?
|
7
7
|
return input if input.is_a? Rule
|
8
8
|
|
9
|
-
Rule.
|
9
|
+
Rule.instance(input).freeze
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
attr_reader :hash
|
12
|
+
class Rule
|
13
|
+
attr_reader :hash, :mode, :values
|
14
14
|
|
15
|
-
def
|
16
|
-
|
17
|
-
when :none, :all then [
|
15
|
+
def self.instance(input)
|
16
|
+
mode, values = case input
|
17
|
+
when :none, :all then [input, nil]
|
18
18
|
when Hash
|
19
|
-
if
|
20
|
-
raise ParamsReadyError, "Unexpected hash for rule: '#{
|
19
|
+
if input.length > 1 || input.length < 1
|
20
|
+
raise ParamsReadyError, "Unexpected hash for rule: '#{input}'"
|
21
21
|
end
|
22
|
-
key, values =
|
22
|
+
key, values = input.first
|
23
23
|
case key
|
24
24
|
when :except, :only then [key, values.to_set.freeze]
|
25
25
|
else
|
26
26
|
raise ParamsReadyError, "Unexpected mode for rule: '#{key}'"
|
27
27
|
end
|
28
28
|
else
|
29
|
-
raise ParamsReadyError, "Unexpected input for rule: '#{
|
29
|
+
raise ParamsReadyError, "Unexpected input for rule: '#{input}'"
|
30
30
|
end
|
31
|
-
|
31
|
+
new(mode, values)
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(mode, values)
|
35
|
+
@mode = mode
|
36
|
+
@values = values.freeze
|
32
37
|
@hash = [@mode, @values].hash
|
33
38
|
freeze
|
34
39
|
end
|
35
40
|
|
41
|
+
def merge(other)
|
42
|
+
return self if other.nil?
|
43
|
+
raise ParamsReadyError, "Can't merge with #{other.class.name}" unless other.is_a? Rule
|
44
|
+
raise ParamsReadyError, "Can't merge incompatible rules: #{mode}/#{other.mode}" if other.mode != mode
|
45
|
+
|
46
|
+
case mode
|
47
|
+
when :all, :none
|
48
|
+
self
|
49
|
+
when :only, :except
|
50
|
+
values = self.values + other.values
|
51
|
+
Rule.new(mode, values)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
36
55
|
def include?(name)
|
37
56
|
case @mode
|
38
57
|
when :none then false
|
@@ -3,16 +3,34 @@ require_relative 'rule'
|
|
3
3
|
module ParamsReady
|
4
4
|
module Helpers
|
5
5
|
class UsageRule
|
6
|
-
attr_reader :parameter_definition
|
6
|
+
attr_reader :parameter_definition, :rule
|
7
7
|
|
8
8
|
def initialize(parameter_definition, rule = :all)
|
9
9
|
@parameter_definition = parameter_definition
|
10
10
|
@rule = ParamsReady::Helpers::Rule(rule)
|
11
|
+
freeze
|
11
12
|
end
|
12
13
|
|
13
|
-
def valid_for(method)
|
14
|
+
def valid_for?(method)
|
14
15
|
@rule.include? method
|
15
16
|
end
|
17
|
+
|
18
|
+
def name
|
19
|
+
parameter_definition.name
|
20
|
+
end
|
21
|
+
|
22
|
+
def merge(other)
|
23
|
+
return self if other.nil?
|
24
|
+
raise ParamsReadyError, "Can't merge into #{other.class.name}" unless other.is_a? UsageRule
|
25
|
+
|
26
|
+
unless parameter_definition == other.parameter_definition
|
27
|
+
message = "Can't merge incompatible rules: #{parameter_definition.name}/#{other.parameter_definition.name}"
|
28
|
+
raise ParamsReadyError, message
|
29
|
+
end
|
30
|
+
|
31
|
+
rule = self.rule.merge(other.rule)
|
32
|
+
UsageRule.new(parameter_definition, rule)
|
33
|
+
end
|
16
34
|
end
|
17
35
|
end
|
18
|
-
end
|
36
|
+
end
|
@@ -47,7 +47,7 @@ module ParamsReady
|
|
47
47
|
freeze
|
48
48
|
end
|
49
49
|
|
50
|
-
module
|
50
|
+
module StructMarshaller
|
51
51
|
extend AbstractMarshaller
|
52
52
|
|
53
53
|
def self.canonicalize(definition, hash, context, validator)
|
@@ -58,7 +58,8 @@ module ParamsReady
|
|
58
58
|
found, count = Helpers::FindInHash.find_in_hash hash, count_key
|
59
59
|
raise ParamsReadyError, "Count not found" unless found
|
60
60
|
|
61
|
-
|
61
|
+
base = 10 if count.is_a? String
|
62
|
+
count = Integer(count, base)
|
62
63
|
array = (0...count).map do |index|
|
63
64
|
found, value = Helpers::FindInHash.find_in_hash hash, index
|
64
65
|
element = definition.prototype.create
|
@@ -120,7 +121,7 @@ module ParamsReady
|
|
120
121
|
@collection ||= begin
|
121
122
|
c = ClassCollection.new Array
|
122
123
|
c.add_instance Array, ArrayMarshaller
|
123
|
-
c.add_instance Hash,
|
124
|
+
c.add_instance Hash, StructMarshaller
|
124
125
|
c.add_factory :string, StringMarshaller
|
125
126
|
c.default!(Hash)
|
126
127
|
c.freeze
|