adaptiveconfiguration 1.0.0.beta06 → 1.0.0.beta07

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e6d7ffc7756d8ea2cb2d685ef00ca01561d232c99852516b38b7bf1ce72cb66
4
- data.tar.gz: bb716f63caf1e4fec6a90da636a30a4bcfc7b546f610d548f275bb630780f2bc
3
+ metadata.gz: 1bddcf16845596d56add432ccd7aefe97a9764b1e99a644b9947427ef49819a2
4
+ data.tar.gz: bf5c024845348795609942aace53b06da90b5f0cfa8e531bf26569554e57c2cb
5
5
  SHA512:
6
- metadata.gz: fbb8df8e89fab329b3ca8464a8088c0617b800ab981be36cae596debb7f29a26b2768520665926d2a30148074f981d59dbbade409932b5c02407efdcb600b5cc
7
- data.tar.gz: ae9e3c1d6fde00f4136edf6e4cc9cb85e621170f78ba52c86211bb1121e3bfe20e9e76fb606bd009e218957c0a6260a127e03342c494cb733d4803d2ad8973ec
6
+ metadata.gz: a4d2af44187899024e1c2a4edbb7e811a613b438ee87a63badc87a3574a8740b6217289463cdc286d0312f4e353958c00a89c69b4dab9e6f93221446dc7ed1f8
7
+ data.tar.gz: 7a247388fdad9d6c99e2c2f6dd78e8490a0cfe5ce8172fb0388c25e19f5e2e4ef579c5613b614c29ce8cb56bc231f605473a064594c110307adc282722f2f924
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do | spec |
2
2
 
3
3
  spec.name = 'adaptiveconfiguration'
4
- spec.version = '1.0.0.beta06'
4
+ spec.version = '1.0.0.beta07'
5
5
  spec.authors = [ 'Kristoph Cichocki-Romanov' ]
6
6
  spec.email = [ 'rubygems.org@kristoph.net' ]
7
7
 
@@ -1,5 +1,5 @@
1
1
  require_relative 'group_builder'
2
- require_relative 'context'
2
+ require_relative 'scaffold'
3
3
 
4
4
  # types must be included to support conversation
5
5
  require 'time'
@@ -49,19 +49,123 @@ module AdaptiveConfiguration
49
49
  end
50
50
 
51
51
  def build( values = nil, &block )
52
- context = AdaptiveConfiguration::Context.new(
52
+ scaffold = AdaptiveConfiguration::Scaffold.new(
53
53
  values,
54
54
  converters: @converters,
55
55
  definitions: @definitions
56
56
  )
57
- context.instance_eval( &block ) if block
58
- context
57
+ scaffold.instance_eval( &block ) if block
58
+ scaffold.to_h
59
59
  end
60
60
 
61
61
  def build!( values = nil, &block )
62
- context = self.build( values, &block )
63
- context.validate!
64
- context
62
+ scaffold = AdaptiveConfiguration::Scaffold.new(
63
+ values,
64
+ converters: @converters,
65
+ definitions: @definitions
66
+ )
67
+ scaffold.instance_eval( &block ) if block
68
+ result = scaffold.to_h
69
+ validate!( result )
70
+ result
71
+ end
72
+
73
+ def validate!( values )
74
+ traverse_and_validate_values( values, definitions: @definitions ) { | error |
75
+ raise error
76
+ }
77
+ end
78
+
79
+ def validate( values )
80
+ errors = []
81
+ traverse_and_validate_values( values, definitions: @definitions ) { | error |
82
+ errors << error
83
+ }
84
+ errors
85
+ end
86
+
87
+ def valid?( values )
88
+ traverse_and_validate_values( values, definitions: @definitions ) {
89
+ return false
90
+ }
91
+ return true
92
+ end
93
+
94
+ protected
95
+
96
+ def value_matches_types?( value, types )
97
+ type_match = false
98
+ Array( types ).each do | type |
99
+ type_match = value.is_a?( type )
100
+ break if type_match
101
+ end
102
+ type_match
103
+ end
104
+
105
+ def traverse_and_validate_values( values, definitions:, path: nil, options: nil, &block )
106
+
107
+ path.chomp( '/' ) if path
108
+ unless values.is_a?( Hash )
109
+ # TODO: raise error
110
+ return
111
+ end
112
+
113
+ definitions.each do | key, definition |
114
+
115
+ name = definition[ :as ] || key
116
+ value = values[ name ]
117
+
118
+ if definition[ :required ] &&
119
+ ( !value || ( value.respond_to?( :empty ) && value.empty? ) )
120
+ block.call( RequirementUnmetError.new( path: path, key: key ) )
121
+ elsif !definition[ :default_assigned ] && !value.nil?
122
+ unless definition[ :array ]
123
+ if definition[ :type ] == :group
124
+ traverse_and_validate_values(
125
+ values[ name ],
126
+ definitions: definition[ :definitions ],
127
+ path: "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }",
128
+ &block
129
+ )
130
+ else
131
+ if definition[ :type ] && value && !definition[ :default_assigned ]
132
+ unless value_matches_types?( value, definition[ :type ] )
133
+ block.call( IncompatibleTypeError.new(
134
+ path: path, key: key, type: definition[ :type ], value: value
135
+ ) )
136
+ end
137
+ end
138
+ end
139
+ else
140
+ if definition[ :type ] == :group
141
+ groups = Array( value )
142
+ groups.each do | group |
143
+ traverse_and_validate_values(
144
+ group,
145
+ definitions: definition[ :definitions ],
146
+ path: "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }",
147
+ &block
148
+ )
149
+ end
150
+ else
151
+ if definition[ :type ] && !definition[ :default_assigned ]
152
+ value_array = Array( value )
153
+ value_array.each do | v |
154
+ unless value_matches_types?( v, definition[ :type ] )
155
+ block.call( IncompatibleTypeError.new(
156
+ path: path, key: key, type: definition[ :type ], value: v
157
+ ) )
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ nil
168
+
65
169
  end
66
170
 
67
171
  end
@@ -1,4 +1,4 @@
1
- require_relative 'context'
1
+ require_relative 'scaffold'
2
2
 
3
3
  module AdaptiveConfiguration
4
4
  class GroupBuilder
@@ -14,8 +14,8 @@ module AdaptiveConfiguration
14
14
  name = name.to_sym
15
15
  options = nil
16
16
 
17
- raise NameError, "The parameter #{name} cannot be used." \
18
- if AdaptiveConfiguration::Context.instance_methods.include?( name )
17
+ raise NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
18
+ if AdaptiveConfiguration::Scaffold.instance_methods.include?( name )
19
19
 
20
20
  if args.first.is_a?( ::Hash )
21
21
  # when called without type: parameter :stream, as: :streams
@@ -30,12 +30,17 @@ module AdaptiveConfiguration
30
30
  end
31
31
 
32
32
  def group( name, options = {}, &block )
33
+
34
+ raise NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
35
+ if AdaptiveConfiguration::Scaffold.instance_methods.include?( name )
36
+
33
37
  builder = GroupBuilder.new
34
38
  builder.instance_eval( &block ) if block
35
39
  @definitions[ name ] = options.merge( {
36
40
  type: :group,
37
41
  definitions: builder.definitions
38
42
  } )
43
+
39
44
  end
40
45
 
41
46
  end
@@ -1,5 +1,5 @@
1
1
  module AdaptiveConfiguration
2
- class Context < BasicObject
2
+ class Scaffold < BasicObject
3
3
 
4
4
  include ::PP::ObjectMixin if defined?( ::PP )
5
5
 
@@ -35,40 +35,12 @@ module AdaptiveConfiguration
35
35
  @values.empty?
36
36
  end
37
37
 
38
- def key?( key )
39
- @values.key?( key )
40
- end
41
-
42
- def []( key )
43
- @values[ key ]
44
- end
45
-
46
- def []=( key, value )
47
- @values[ key ] = value
48
- end
49
-
50
- def each( &block )
51
- @values.each( &block )
52
- end
53
-
54
-
55
- def merge( hash )
56
- self.to_h.merge( hash )
57
- end
58
-
59
- def valid?
60
- __validate_values
61
- @errors.empty?
62
- end
63
-
64
- def validate!
65
- __validate_values { | error | ::Kernel.raise error }
66
- end
67
-
68
38
  def to_h
69
39
  recursive_to_h = ->( object ) do
70
40
  case object
71
- when ::AdaptiveConfiguration::Context
41
+ when ::NilClass
42
+ nil
43
+ when ::AdaptiveConfiguration::Scaffold
72
44
  recursive_to_h.call( object.to_h )
73
45
  when ::Hash
74
46
  object.transform_values { | value | recursive_to_h.call( value ) }
@@ -86,10 +58,6 @@ module AdaptiveConfiguration
86
58
  inspect
87
59
  end
88
60
 
89
- def to_yaml
90
- self.to_h.to_yaml
91
- end
92
-
93
61
  def inspect
94
62
  { values: @values, definitions: @definitions }.inspect
95
63
  end
@@ -101,11 +69,11 @@ module AdaptiveConfiguration
101
69
  end
102
70
 
103
71
  def class
104
- ::AdaptiveConfiguration::Context
72
+ ::AdaptiveConfiguration::Scaffold
105
73
  end
106
74
 
107
75
  def is_a?( klass )
108
- klass == ::AdaptiveConfiguration::Context || klass == ::BasicObject
76
+ klass == ::AdaptiveConfiguration::Scaffold || klass == ::BasicObject
109
77
  end
110
78
 
111
79
  alias :kind_of? :is_a?
@@ -118,12 +86,12 @@ module AdaptiveConfiguration
118
86
 
119
87
  unless definition[ :array ]
120
88
  if definition[ :type ] == :group
121
- argument = args.first
89
+ value = args.first
122
90
  context = @values[ name ]
123
- if context.nil? || argument
91
+ if context.nil? || value
124
92
  context =
125
- Context.new(
126
- argument,
93
+ Scaffold.new(
94
+ value,
127
95
  converters: @converters,
128
96
  definitions: definition[ :definitions ]
129
97
  )
@@ -142,7 +110,7 @@ module AdaptiveConfiguration
142
110
  if definition[ :type ] == :group
143
111
  values = [ args.first ].flatten
144
112
  values = values.map do | v |
145
- context = Context.new(
113
+ context = Scaffold.new(
146
114
  v,
147
115
  converters: @converters,
148
116
  definitions: definition[ :definitions ]
@@ -165,7 +133,6 @@ module AdaptiveConfiguration
165
133
 
166
134
  definition[ :default_assigned ] = false
167
135
  @values[ name ]
168
-
169
136
  else
170
137
  super
171
138
  end
@@ -206,78 +173,5 @@ module AdaptiveConfiguration
206
173
  result
207
174
  end
208
175
 
209
- def __validate_values( path = nil, &block )
210
-
211
- path.chomp( '/' ) if path
212
- @errors = []
213
-
214
- is_of_matching_types = ::Proc.new do | value, types |
215
- type_match = false
216
- ::Kernel.method( :Array ).call( types ).each do | type |
217
- type_match = value.is_a?( type )
218
- break if type_match
219
- end
220
- type_match
221
- end
222
-
223
- @definitions.each do | key, definition |
224
-
225
- name = definition[ :as ] || key
226
- value = @values[ name ]
227
-
228
- if definition[ :required ] &&
229
- ( !value || ( value.respond_to?( :empty ) && value.empty? ) )
230
-
231
- error = RequirementUnmetError.new( path: path, key: key )
232
- block.call( error ) if block
233
- @errors << error
234
-
235
- elsif !definition[ :default_assigned ] && !value.nil?
236
-
237
- unless definition[ :array ]
238
-
239
- if definition[ :type ] == :group
240
- value.__validate_values( "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }", &block )
241
- @errors.concat( value.errors )
242
- else
243
- if definition[ :type ] && value && !definition[ :default_assigned ]
244
- unless is_of_matching_types.call( value, definition[ :type ] )
245
- error = IncompatibleTypeError.new(
246
- path: path, key: key, type: definition[ :type ], value: value
247
- )
248
- block.call( error ) if block
249
- @errors << error
250
- end
251
- end
252
- end
253
-
254
- else
255
-
256
- if definition[ :type ] == :group
257
- groups = ::Kernel.method( :Array ).call( value )
258
- groups.each do | group |
259
- group.__validate_values( "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }", &block )
260
- @errors.concat( group.errors )
261
- end
262
- else
263
- if definition[ :type ] && !definition[ :default_assigned ]
264
- values = ::Kernel.method( :Array ).call( value )
265
- values.each do | v |
266
- unless is_of_matching_types.call( v, definition[ :type ] )
267
- error = IncompatibleTypeError.new(
268
- path: path, key: key, type: definition[ :type ], value: v
269
- )
270
- block.call( error ) if block
271
- @errors << error
272
- end
273
- end
274
- end
275
- end
276
-
277
- end
278
- end
279
- end
280
- end
281
-
282
176
  end
283
177
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adaptiveconfiguration
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta06
4
+ version: 1.0.0.beta07
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristoph Cichocki-Romanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-09 00:00:00.000000000 Z
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -57,9 +57,9 @@ files:
57
57
  - lib/adaptive_configuration.rb
58
58
  - lib/adaptive_configuration/builder.rb
59
59
  - lib/adaptive_configuration/configurable.rb
60
- - lib/adaptive_configuration/context.rb
61
60
  - lib/adaptive_configuration/errors.rb
62
61
  - lib/adaptive_configuration/group_builder.rb
62
+ - lib/adaptive_configuration/scaffold.rb
63
63
  homepage: https://github.com/EndlessInternational/adaptive_configuration
64
64
  licenses:
65
65
  - MIT