qonfig 0.12.0 → 0.13.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +457 -137
- data/lib/qonfig/command_set.rb +7 -1
- data/lib/qonfig/commands/add_nested_option.rb +3 -1
- data/lib/qonfig/commands/add_option.rb +2 -1
- data/lib/qonfig/commands/base.rb +2 -1
- data/lib/qonfig/commands/compose.rb +16 -10
- data/lib/qonfig/commands/expose_yaml.rb +2 -1
- data/lib/qonfig/commands/load_from_env.rb +2 -1
- data/lib/qonfig/commands/load_from_json.rb +2 -1
- data/lib/qonfig/commands/load_from_self.rb +2 -1
- data/lib/qonfig/commands/load_from_yaml.rb +2 -1
- data/lib/qonfig/data_set/lock.rb +46 -0
- data/lib/qonfig/data_set.rb +92 -23
- data/lib/qonfig/errors.rb +8 -0
- data/lib/qonfig/plugins/toml/commands/expose_toml.rb +2 -1
- data/lib/qonfig/plugins/toml/commands/load_from_toml.rb +2 -1
- data/lib/qonfig/settings/builder.rb +20 -4
- data/lib/qonfig/settings/callbacks.rb +43 -0
- data/lib/qonfig/settings/key_matcher.rb +175 -0
- data/lib/qonfig/settings/lock.rb +3 -3
- data/lib/qonfig/settings.rb +144 -33
- data/lib/qonfig/validator/basic.rb +53 -0
- data/lib/qonfig/validator/builder/attribute_consistency.rb +181 -0
- data/lib/qonfig/validator/builder.rb +169 -0
- data/lib/qonfig/validator/collection.rb +73 -0
- data/lib/qonfig/validator/dsl.rb +51 -0
- data/lib/qonfig/validator/method_based.rb +49 -0
- data/lib/qonfig/validator/predefined/common.rb +53 -0
- data/lib/qonfig/validator/predefined/registry.rb +83 -0
- data/lib/qonfig/validator/predefined/registry_control_mixin.rb +43 -0
- data/lib/qonfig/validator/predefined.rb +41 -0
- data/lib/qonfig/validator/proc_based.rb +53 -0
- data/lib/qonfig/validator.rb +58 -0
- data/lib/qonfig/version.rb +1 -1
- data/lib/qonfig.rb +1 -0
- data/qonfig.gemspec +1 -1
- metadata +19 -5
- data/lib/qonfig/data_set/validator.rb +0 -7
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::Builder::AttributeConsistency
|
6
|
+
class << self
|
7
|
+
# @param setting_key_pattern [String, Symbol, NilClass]
|
8
|
+
# @param predefined_validator [String, Symbol, NilClass]
|
9
|
+
# @param runtime_validation_method [String, Symbol, NilClass]
|
10
|
+
# @param validation_logic [Proc, NilClass]
|
11
|
+
# @return [void]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
# @since 0.13.0
|
15
|
+
def check!(
|
16
|
+
setting_key_pattern,
|
17
|
+
predefined_validator,
|
18
|
+
runtime_validation_method,
|
19
|
+
validation_logic
|
20
|
+
)
|
21
|
+
new(
|
22
|
+
setting_key_pattern,
|
23
|
+
predefined_validator,
|
24
|
+
runtime_validation_method,
|
25
|
+
validation_logic
|
26
|
+
).check!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param setting_key_pattern [String, Symbol, NilClass]
|
31
|
+
# @param predefined_validator [String, Symbol, NilClass]
|
32
|
+
# @param runtime_validation_method [String, Symbol, NilClass]
|
33
|
+
# @param validation_logic [Proc, NilClass]
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.13.0
|
38
|
+
def initialize(
|
39
|
+
setting_key_pattern,
|
40
|
+
predefined_validator,
|
41
|
+
runtime_validation_method,
|
42
|
+
validation_logic
|
43
|
+
)
|
44
|
+
@setting_key_pattern = setting_key_pattern
|
45
|
+
@predefined_validator = predefined_validator
|
46
|
+
@runtime_validation_method = runtime_validation_method
|
47
|
+
@validation_logic = validation_logic
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [void]
|
51
|
+
#
|
52
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
53
|
+
#
|
54
|
+
# @api private
|
55
|
+
# @since 0.13.0
|
56
|
+
def check!
|
57
|
+
consistent_method_choice!
|
58
|
+
consistent_predefined_validator!
|
59
|
+
cosnistent_runtime_validation_method!
|
60
|
+
consistent_validation_logic!
|
61
|
+
consistent_setting_key_pattern!
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# @return [String, Symbol, NilClass]
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
# @since 0.13.0
|
70
|
+
attr_reader :setting_key_pattern
|
71
|
+
|
72
|
+
# @return [String, Symbol, NilClass]
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
# @since 0.13.0
|
76
|
+
attr_reader :predefined_validator
|
77
|
+
|
78
|
+
# @return [String, Symbol, NilClass]
|
79
|
+
#
|
80
|
+
# @api private
|
81
|
+
# @since 0.13.0
|
82
|
+
attr_reader :runtime_validation_method
|
83
|
+
|
84
|
+
# @return [Proc, NilClass]
|
85
|
+
#
|
86
|
+
# @api private
|
87
|
+
# @since 0.13.0
|
88
|
+
attr_reader :validation_logic
|
89
|
+
|
90
|
+
# @return [void]
|
91
|
+
#
|
92
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
93
|
+
#
|
94
|
+
# @api private
|
95
|
+
# @since 0.13.0
|
96
|
+
def consistent_method_choice!
|
97
|
+
unless runtime_validation_method || validation_logic || predefined_validator
|
98
|
+
raise(
|
99
|
+
Qonfig::ValidatorArgumentError,
|
100
|
+
'Empty validation (you should provide: dataset method OR proc OR predefined validator)'
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
if ((runtime_validation_method && validation_logic) ||
|
105
|
+
(predefined_validator && (runtime_validation_method || validation_logic)))
|
106
|
+
raise(
|
107
|
+
Qonfig::ValidatorArgumentError,
|
108
|
+
'Incosistent validation (you should use: dataset method OR proc OR predefined validator)'
|
109
|
+
)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [void]
|
114
|
+
#
|
115
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
# @since 0.13.0
|
119
|
+
def consistent_predefined_validator!
|
120
|
+
return if predefined_validator.nil?
|
121
|
+
return if predefined_validator.is_a?(Symbol)
|
122
|
+
return if predefined_validator.is_a?(String)
|
123
|
+
|
124
|
+
raise(
|
125
|
+
Qonfig::ValidatorArgumentError,
|
126
|
+
'Incorrect name of predefined validator (should be a symbol or a string)'
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [void]
|
131
|
+
#
|
132
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
133
|
+
#
|
134
|
+
# @api private
|
135
|
+
# @since 0.13.0
|
136
|
+
def cosnistent_runtime_validation_method!
|
137
|
+
return if runtime_validation_method.nil?
|
138
|
+
return if runtime_validation_method.is_a?(Symbol)
|
139
|
+
return if runtime_validation_method.is_a?(String)
|
140
|
+
|
141
|
+
raise(
|
142
|
+
Qonfig::ValidatorArgumentError,
|
143
|
+
'Incompatible validation method name (should be a symbol or a string)'
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
# @return [void]
|
148
|
+
#
|
149
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
150
|
+
#
|
151
|
+
# @api private
|
152
|
+
# @since 0.13.0
|
153
|
+
def consistent_validation_logic!
|
154
|
+
return if validation_logic.nil?
|
155
|
+
return if validation_logic.is_a?(Proc)
|
156
|
+
|
157
|
+
# :nocov:
|
158
|
+
raise(
|
159
|
+
Qonfig::ValidatorArgumentError,
|
160
|
+
'Incompatible validation object (should be a proc)'
|
161
|
+
)
|
162
|
+
# :nocov:
|
163
|
+
end
|
164
|
+
|
165
|
+
# @return [void]
|
166
|
+
#
|
167
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
168
|
+
#
|
169
|
+
# @api private
|
170
|
+
# @since 0.13.0
|
171
|
+
def consistent_setting_key_pattern!
|
172
|
+
return if setting_key_pattern.nil?
|
173
|
+
return if setting_key_pattern.is_a?(Symbol)
|
174
|
+
return if setting_key_pattern.is_a?(String)
|
175
|
+
|
176
|
+
raise(
|
177
|
+
Qonfig::ValidatorArgumentError,
|
178
|
+
'Incompatible setting key pattern (should be a string or a symbol)'
|
179
|
+
)
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::Builder
|
6
|
+
require_relative 'builder/attribute_consistency'
|
7
|
+
|
8
|
+
# @return [NilClass]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.13.0
|
12
|
+
EMPTY_SETTING_KEY_PATTERN = nil
|
13
|
+
|
14
|
+
# @return [NilClass]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.13.0
|
18
|
+
NO_RUNTIME_VALIDATION_METHOD = nil
|
19
|
+
|
20
|
+
# @return [NilClass]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
# @since 0.13.0
|
24
|
+
NO_VALIDATION_LOGIC = nil
|
25
|
+
|
26
|
+
# @return [NilClass]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.13.0
|
30
|
+
NO_PREDEFINED_VALIDATOR = nil
|
31
|
+
|
32
|
+
class << self
|
33
|
+
# @option setting_key_pattern [String, Symbol, NilClass]
|
34
|
+
# @option predefined_validator [String, Symbol, NilClass]
|
35
|
+
# @option runtime_validation_method [String, Symbol, NilClass]
|
36
|
+
# @option validation_logic [Proc, NilClass]
|
37
|
+
# @return [Qonfig::Validator::MethodBased, Qonfig::Validator::ProcBased]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
# @since 0.13.0
|
41
|
+
def build(
|
42
|
+
setting_key_pattern: EMPTY_SETTING_KEY_PATTERN,
|
43
|
+
runtime_validation_method: NO_RUNTIME_VALIDATION_METHOD,
|
44
|
+
validation_logic: NO_VALIDATION_LOGIC,
|
45
|
+
predefined_validator: NO_PREDEFINED_VALIDATOR
|
46
|
+
)
|
47
|
+
new(
|
48
|
+
setting_key_pattern,
|
49
|
+
predefined_validator,
|
50
|
+
runtime_validation_method,
|
51
|
+
validation_logic
|
52
|
+
).build
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @param setting_key_pattern [String, Symbol, NilClass]
|
57
|
+
# @param predefined_validator [String, Symbol, NilClass]
|
58
|
+
# @param runtime_validation_method [String, Symbol, NilClass]
|
59
|
+
# @param validation_logic [Proc, NilClass]
|
60
|
+
# @return [void]
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
# @since 0.13.0
|
64
|
+
def initialize(
|
65
|
+
setting_key_pattern,
|
66
|
+
predefined_validator,
|
67
|
+
runtime_validation_method,
|
68
|
+
validation_logic
|
69
|
+
)
|
70
|
+
@setting_key_pattern = setting_key_pattern
|
71
|
+
@predefined_validator = predefined_validator
|
72
|
+
@runtime_validation_method = runtime_validation_method
|
73
|
+
@validation_logic = validation_logic
|
74
|
+
end
|
75
|
+
|
76
|
+
# @return [Qonfig::Validator::MethodBased, Qonfig::Validator::ProcBased]
|
77
|
+
#
|
78
|
+
# @api private
|
79
|
+
# @since 0.13.0
|
80
|
+
def build
|
81
|
+
validate_attributes!
|
82
|
+
build_validator
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# @return [String, Symbol, NilClass]
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
# @since 0.13.0
|
91
|
+
attr_reader :setting_key_pattern
|
92
|
+
|
93
|
+
# @return [String, Symbol, NilClass]
|
94
|
+
#
|
95
|
+
# @api private
|
96
|
+
# @since 0.13.0
|
97
|
+
attr_reader :predefined_validator
|
98
|
+
|
99
|
+
# @return [String, Symbol, NilClass]
|
100
|
+
#
|
101
|
+
# @api private
|
102
|
+
# @since 0.13.0
|
103
|
+
attr_reader :runtime_validation_method
|
104
|
+
|
105
|
+
# @return [Proc, NilClass]
|
106
|
+
#
|
107
|
+
# @api private
|
108
|
+
# @since 0.13.0
|
109
|
+
attr_reader :validation_logic
|
110
|
+
|
111
|
+
# @return [void]
|
112
|
+
#
|
113
|
+
# @raise [Qonfig::ArgumentError]
|
114
|
+
#
|
115
|
+
# @api private
|
116
|
+
# @since 0.13.0
|
117
|
+
def validate_attributes!
|
118
|
+
AttributeConsistency.check!(
|
119
|
+
setting_key_pattern,
|
120
|
+
predefined_validator,
|
121
|
+
runtime_validation_method,
|
122
|
+
validation_logic
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [Qonfig::Validator::MethodBased, Qonfig::Validator::PorcBased]
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
# @since 0.13.0
|
130
|
+
def build_validator
|
131
|
+
case
|
132
|
+
when predefined_validator then build_predefined
|
133
|
+
when runtime_validation_method then build_method_based
|
134
|
+
when validation_logic then build_proc_based
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# @return [Qonfig::Settings::KeyMatcher, NilClass]
|
139
|
+
#
|
140
|
+
# @api private
|
141
|
+
# @since 0.13.0
|
142
|
+
def build_setting_key_matcher
|
143
|
+
Qonfig::Settings::KeyMatcher.new(setting_key_pattern.to_s) if setting_key_pattern
|
144
|
+
end
|
145
|
+
|
146
|
+
# @return [Qonfig::Validator::MethodBased]
|
147
|
+
#
|
148
|
+
# @api private
|
149
|
+
# @since 0.13.0
|
150
|
+
def build_method_based
|
151
|
+
Qonfig::Validator::MethodBased.new(build_setting_key_matcher, runtime_validation_method)
|
152
|
+
end
|
153
|
+
|
154
|
+
# @return [Qonfig::Validator::ProcBased]
|
155
|
+
#
|
156
|
+
# @api private
|
157
|
+
# @since 0.13.0
|
158
|
+
def build_proc_based
|
159
|
+
Qonfig::Validator::ProcBased.new(build_setting_key_matcher, validation_logic)
|
160
|
+
end
|
161
|
+
|
162
|
+
# @return [Qonfig::Settings::Predefined]
|
163
|
+
#
|
164
|
+
# @api private
|
165
|
+
# @since 0.13.0
|
166
|
+
def build_predefined
|
167
|
+
Qonfig::Validator::Predefined.build(predefined_validator, build_setting_key_matcher)
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::Collection
|
6
|
+
# @api private
|
7
|
+
# @since 0.13.0
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# @return [Array<Qonfig::Validator::MethodBased,Qonfig::Validator::ProcBased>]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.13.0
|
14
|
+
attr_reader :validators
|
15
|
+
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.13.0
|
20
|
+
def initialize
|
21
|
+
@validators = []
|
22
|
+
@access_lock = Mutex.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param validator [Qonfig::Validator::MethodBased, Qonfig::Validator::ProcBased]
|
26
|
+
# @return [void]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.13.0
|
30
|
+
def add_validator(validator)
|
31
|
+
thread_safe { validators << validator }
|
32
|
+
end
|
33
|
+
alias_method :<<, :add_validator
|
34
|
+
|
35
|
+
# @param block [Proc]
|
36
|
+
# @return [Enumerable]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.13.0
|
40
|
+
def each(&block)
|
41
|
+
thread_safe { block_given? ? validators.each(&block) : validators.each }
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param collection [Qonfig::Validator::Collection]
|
45
|
+
# @return [void]
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
# @since 0.13.0
|
49
|
+
def concat(collection)
|
50
|
+
thread_safe { validators.concat(collection.validators) }
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Qonfig::Validator::Collection]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
# @since 0.13.0
|
57
|
+
def dup
|
58
|
+
thread_safe do
|
59
|
+
self.class.new.tap { |duplicate| duplicate.concat(self) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# @param block [Proc]
|
66
|
+
# @return [Any]
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
# @since 0.13.0
|
70
|
+
def thread_safe(&block)
|
71
|
+
@access_lock.synchronize(&block)
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
module Qonfig::Validator::DSL
|
6
|
+
class << self
|
7
|
+
# @param child_klass [Qonfig::DataSet]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.13.0
|
12
|
+
def extended(child_klass)
|
13
|
+
child_klass.instance_variable_set(:@validators, Qonfig::Validator::Collection.new)
|
14
|
+
|
15
|
+
child_klass.singleton_class.prepend(Module.new do
|
16
|
+
def inherited(child_klass)
|
17
|
+
child_klass.instance_variable_set(:@validators, Qonfig::Validator::Collection.new)
|
18
|
+
child_klass.validators.concat(validators)
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Qonfig::Validator::Collection]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.13.0
|
29
|
+
def validators
|
30
|
+
@validators
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param setting_key_pattern [String, Symbol, NilClass]
|
34
|
+
# @param predefined [String, Symbol]
|
35
|
+
# @option by [String, Symbol, NilClass]
|
36
|
+
# @param custom_validation [Proc]
|
37
|
+
# @return [void]
|
38
|
+
#
|
39
|
+
# @see Qonfig::Validator::Builder
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
# @since 0.13.0
|
43
|
+
def validate(setting_key_pattern = nil, predefined = nil, by: nil, &custom_validation)
|
44
|
+
validators << Qonfig::Validator::Builder.build(
|
45
|
+
setting_key_pattern: setting_key_pattern,
|
46
|
+
predefined_validator: predefined,
|
47
|
+
runtime_validation_method: by,
|
48
|
+
validation_logic: custom_validation
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::MethodBased < Qonfig::Validator::Basic
|
6
|
+
# @return [Symbol, String]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.13.0
|
10
|
+
attr_reader :runtime_validation_method
|
11
|
+
|
12
|
+
# @param setting_key_matcher [Qonfig::Settings::KeyMatcher, NilClass]
|
13
|
+
# @param runtime_validation_method [String, Symbol]
|
14
|
+
# @return [void]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.13.0
|
18
|
+
def initialize(setting_key_matcher, runtime_validation_method)
|
19
|
+
super(setting_key_matcher)
|
20
|
+
@runtime_validation_method = runtime_validation_method
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param data_set [Qonfig::DataSet]
|
24
|
+
# @return [Boolean]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.13.0
|
28
|
+
def validate_concrete(data_set)
|
29
|
+
data_set.settings.__deep_each_setting__ do |setting_key, setting_value|
|
30
|
+
next unless setting_key_matcher.match?(setting_key)
|
31
|
+
|
32
|
+
raise(
|
33
|
+
Qonfig::ValidationError,
|
34
|
+
"Invalid value of setting <#{setting_key}> (#{setting_value})"
|
35
|
+
) unless data_set.__send__(runtime_validation_method, setting_value)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @param data_set [Qonfig::DataSet]
|
40
|
+
# @return [Boolean]
|
41
|
+
#
|
42
|
+
# @api private
|
43
|
+
# @since 0.13.0
|
44
|
+
def validate_full(data_set)
|
45
|
+
unless data_set.__send__(runtime_validation_method)
|
46
|
+
raise(Qonfig::ValidationError, 'Invalid config object')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::Predefined::Common < Qonfig::Validator::Basic
|
6
|
+
# @return [Proc]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.13.0
|
10
|
+
attr_reader :validation
|
11
|
+
|
12
|
+
# @param setting_key_matcher [Qonfig::Settings::KeyMatcher]
|
13
|
+
# @param validation [Proc]
|
14
|
+
# @return [void]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.13.0
|
18
|
+
def initialize(setting_key_matcher, validation)
|
19
|
+
super(setting_key_matcher)
|
20
|
+
@validation = validation
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param data_set [Qonfig::DataSet]
|
24
|
+
# @return [void]
|
25
|
+
#
|
26
|
+
# @raise [Qonfig::ValidationError]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.13.0
|
30
|
+
def validate_concrete(data_set)
|
31
|
+
data_set.settings.__deep_each_setting__ do |setting_key, setting_value|
|
32
|
+
next unless setting_key_matcher.match?(setting_key)
|
33
|
+
|
34
|
+
raise(
|
35
|
+
Qonfig::ValidationError,
|
36
|
+
"Invalid value of setting <#{setting_key}> (#{setting_value})"
|
37
|
+
) unless validation.call(setting_value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param data_set [Qonfig::DataSet]
|
42
|
+
# @return [void]
|
43
|
+
#
|
44
|
+
# @raise [Qonfig::ValidationError]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
# @since 0.13.0
|
48
|
+
def validate_full(data_set)
|
49
|
+
# :nocov:
|
50
|
+
raise Qonfig::Error, 'Predefined validator should be used only with a setting key'
|
51
|
+
# :nocov:
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
class Qonfig::Validator::Predefined::Registry
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.13.0
|
10
|
+
def initialize
|
11
|
+
@validators = {}
|
12
|
+
@lock = Mutex.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param name [String, Symbol]
|
16
|
+
# @param validation [Proc]
|
17
|
+
# @return [void]
|
18
|
+
#
|
19
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.13.0
|
23
|
+
def register(name, &validation)
|
24
|
+
thread_safe do
|
25
|
+
name = indifferently_accessable_name(name)
|
26
|
+
|
27
|
+
raise(
|
28
|
+
Qonfig::ValidatorArgumentError,
|
29
|
+
"Predefined validator with name '#{name}' already exists."
|
30
|
+
) if validators.key?(name)
|
31
|
+
|
32
|
+
validators[name] = validation
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param name [String, Symbol]
|
37
|
+
# @return [Qonfig::Validator::ProcBased, Qonfig::Validator::MethodBased]
|
38
|
+
#
|
39
|
+
# @raise [Qonfig::ValidatorArgumentError]
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
# @since 0.13.0
|
43
|
+
def resolve(name)
|
44
|
+
thread_safe do
|
45
|
+
# rubocop:disable Style/RedundantBegin
|
46
|
+
begin
|
47
|
+
validators.fetch(indifferently_accessable_name(name))
|
48
|
+
rescue KeyError
|
49
|
+
raise(
|
50
|
+
Qonfig::ValidatorArgumentError,
|
51
|
+
"Predefined validator with name '#{name}' does not exist."
|
52
|
+
)
|
53
|
+
end
|
54
|
+
# rubocop:enable Style/RedundantBegin
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# @return [Hash<String,Proc>]
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
# @since 0.13.0
|
64
|
+
attr_reader :validators
|
65
|
+
|
66
|
+
# @param name [String, Symbol]
|
67
|
+
# @return [String]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
# @since 0.13.0
|
71
|
+
def indifferently_accessable_name(name)
|
72
|
+
name.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param block [Proc]
|
76
|
+
# @return [Any]
|
77
|
+
#
|
78
|
+
# @api private
|
79
|
+
# @since 0.13.0
|
80
|
+
def thread_safe(&block)
|
81
|
+
@lock.synchronize(&block)
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.13.0
|
5
|
+
module Qonfig::Validator::Predefined::RegistryControlMixin
|
6
|
+
class << self
|
7
|
+
# @param basic_klass [Class, Module]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.13.0
|
12
|
+
def extended(basic_klass)
|
13
|
+
basic_klass.instance_variable_set(:@registry, Qonfig::Validator::Predefined::Registry.new)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Qonfig::Validator::Predefined::Registry]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
# @since 0.13.0
|
21
|
+
attr_reader :registry
|
22
|
+
|
23
|
+
# @param name [String, Symbol]
|
24
|
+
# @param validation [Proc]
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.13.0
|
29
|
+
def predefine(name, &validation)
|
30
|
+
registry.register(name, &validation)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param name [String, Symbol]
|
34
|
+
# @param setting_key_matcher [Qonfig::Setting::KeyMatcher]
|
35
|
+
# @return [Qonfig::Validator::Predefined::Common]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @since 0.13.0
|
39
|
+
def build(name, setting_key_matcher)
|
40
|
+
validation = registry.resolve(name)
|
41
|
+
Qonfig::Validator::Predefined::Common.new(setting_key_matcher, validation)
|
42
|
+
end
|
43
|
+
end
|