dynamicschema 2.0.0 → 2.1.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/README.md +294 -171
- data/dynamicschema.gemspec +2 -2
- data/lib/dynamic_schema/builder.rb +12 -6
- data/lib/dynamic_schema/compiler.rb +14 -9
- data/lib/dynamic_schema/receiver/object.rb +249 -200
- data/lib/dynamic_schema/struct.rb +48 -12
- data/lib/dynamic_schema/validator.rb +39 -5
- metadata +6 -9
|
@@ -40,19 +40,35 @@ module DynamicSchema
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
__compiled_schema.each do | property, criteria |
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
key = ( criteria[ :as ] || property ).to_sym
|
|
45
45
|
type = criteria[ :type ]
|
|
46
46
|
default = criteria[ :default ]
|
|
47
|
+
has_multiple_types = type.is_a?( ::Array ) && criteria[ :compiler ]
|
|
47
48
|
|
|
48
|
-
if
|
|
49
|
+
if has_multiple_types
|
|
50
|
+
define_method( property ) do
|
|
51
|
+
@converted_attributes.fetch( key ) do
|
|
52
|
+
value = @attributes[ key ]
|
|
53
|
+
value = default if value.nil?
|
|
54
|
+
schema = criteria[ :schema ] ||= ( criteria[ :compiler ]&.compiled )
|
|
55
|
+
klass = criteria[ :class ] ||= ( schema ? ::DynamicSchema::Struct.new( schema ) : nil )
|
|
56
|
+
@converted_attributes[ key ] =
|
|
57
|
+
if criteria[ :array ]
|
|
58
|
+
__convert_types_array( Array( value ), klass, criteria )
|
|
59
|
+
else
|
|
60
|
+
__convert_types( value, klass, criteria )
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
elsif type == ::Object
|
|
49
65
|
define_method( property ) do
|
|
50
66
|
@converted_attributes.fetch( key ) do
|
|
51
67
|
value = @attributes[ key ]
|
|
52
68
|
schema = criteria[ :schema ] ||= ( criteria[ :compiler ]&.compiled )
|
|
53
69
|
return value unless schema
|
|
54
70
|
klass = criteria[ :class ] ||= ::DynamicSchema::Struct.new( schema )
|
|
55
|
-
@converted_attributes[ key ] =
|
|
71
|
+
@converted_attributes[ key ] =
|
|
56
72
|
if criteria[ :array ]
|
|
57
73
|
Array( value || default ).map { | v | klass.build( v || {} ) }
|
|
58
74
|
else
|
|
@@ -61,23 +77,23 @@ module DynamicSchema
|
|
|
61
77
|
end
|
|
62
78
|
end
|
|
63
79
|
elsif type
|
|
64
|
-
define_method( property ) do
|
|
65
|
-
@converted_attributes.fetch( key ) do
|
|
66
|
-
value = @attributes[ key ]
|
|
67
|
-
@converted_attributes[ key ] = criteria[ :array ] ?
|
|
68
|
-
Array( value || default ).map { | v | __convert( v, to: type ) } :
|
|
80
|
+
define_method( property ) do
|
|
81
|
+
@converted_attributes.fetch( key ) do
|
|
82
|
+
value = @attributes[ key ]
|
|
83
|
+
@converted_attributes[ key ] = criteria[ :array ] ?
|
|
84
|
+
Array( value || default ).map { | v | __convert( v, to: type ) } :
|
|
69
85
|
__convert( value || default, to: type )
|
|
70
86
|
end
|
|
71
87
|
end
|
|
72
88
|
else
|
|
73
89
|
define_method( property ) do
|
|
74
90
|
@attributes[ key ] || default
|
|
75
|
-
end
|
|
91
|
+
end
|
|
76
92
|
end
|
|
77
93
|
|
|
78
|
-
define_method( :"#{ property }=" ) do | value |
|
|
94
|
+
define_method( :"#{ property }=" ) do | value |
|
|
79
95
|
@converted_attributes.delete( key )
|
|
80
|
-
@attributes[ key ] = value
|
|
96
|
+
@attributes[ key ] = value
|
|
81
97
|
end
|
|
82
98
|
|
|
83
99
|
end
|
|
@@ -96,7 +112,7 @@ module DynamicSchema
|
|
|
96
112
|
result
|
|
97
113
|
end
|
|
98
114
|
|
|
99
|
-
private
|
|
115
|
+
private
|
|
100
116
|
|
|
101
117
|
def compiled_schema
|
|
102
118
|
self.class.compiled_schema
|
|
@@ -123,6 +139,26 @@ module DynamicSchema
|
|
|
123
139
|
self.class.converter.convert( value, to: to ) { | v | to.new( v ) rescue nil }
|
|
124
140
|
end
|
|
125
141
|
|
|
142
|
+
def __convert_types( value, klass, criteria )
|
|
143
|
+
return nil if value.nil?
|
|
144
|
+
if value.is_a?( ::Hash )
|
|
145
|
+
klass ? klass.build( value ) : value
|
|
146
|
+
else
|
|
147
|
+
scalar_types = __non_object_types( criteria[ :type ] )
|
|
148
|
+
__convert( value, to: scalar_types )
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def __convert_types_array( values, klass, criteria )
|
|
153
|
+
values.map { | v | __convert_types( v, klass, criteria ) }
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def __non_object_types( types )
|
|
157
|
+
types_array = types.is_a?( ::Array ) ? types : [ types ]
|
|
158
|
+
result = types_array.reject { | type | type == ::Object }
|
|
159
|
+
result.length == 1 ? result.first : result
|
|
160
|
+
end
|
|
161
|
+
|
|
126
162
|
end
|
|
127
163
|
__klass.instance_variable_set( :@__compiled_schema, __compiled_schema.dup )
|
|
128
164
|
__klass.instance_variable_set( :@__converter, __converter )
|
|
@@ -40,6 +40,33 @@ module DynamicSchema
|
|
|
40
40
|
type_match
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
def __validate_types( value, criteria, path, key, &block )
|
|
44
|
+
if value.is_a?( ::Hash )
|
|
45
|
+
traverse_and_validate_values(
|
|
46
|
+
value,
|
|
47
|
+
schema: criteria[ :schema ] ||= criteria[ :compiler ].compiled,
|
|
48
|
+
path: "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }",
|
|
49
|
+
&block
|
|
50
|
+
)
|
|
51
|
+
else
|
|
52
|
+
scalar_types = __non_object_types( criteria[ :type ] )
|
|
53
|
+
unless value_matches_types?( value, scalar_types )
|
|
54
|
+
block.call( IncompatibleTypeError.new( path: path, key: key, type: criteria[ :type ], value: value ) )
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def __validate_types_array( values, criteria, path, key, &block )
|
|
60
|
+
values.each do | value |
|
|
61
|
+
__validate_types( value, criteria, path, key, &block )
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def __non_object_types( types )
|
|
66
|
+
types_array = types.is_a?( ::Array ) ? types : [ types ]
|
|
67
|
+
types_array.reject { | type | type == ::Object }
|
|
68
|
+
end
|
|
69
|
+
|
|
43
70
|
def traverse_and_validate_values( values, schema:, path: nil, options: nil, &block )
|
|
44
71
|
path.chomp( '/' ) if path
|
|
45
72
|
unless values.respond_to?( :[] )
|
|
@@ -59,8 +86,13 @@ module DynamicSchema
|
|
|
59
86
|
end
|
|
60
87
|
end
|
|
61
88
|
elsif !criteria[ :default_assigned ] && !value.nil?
|
|
89
|
+
type = criteria[ :type ]
|
|
90
|
+
has_multiple_types = type.is_a?( ::Array ) && criteria[ :compiler ]
|
|
91
|
+
|
|
62
92
|
unless criteria[ :array ]
|
|
63
|
-
if
|
|
93
|
+
if has_multiple_types
|
|
94
|
+
__validate_types( value, criteria, path, key, &block )
|
|
95
|
+
elsif type == Object
|
|
64
96
|
traverse_and_validate_values(
|
|
65
97
|
values[ name ],
|
|
66
98
|
schema: criteria[ :schema ] ||= criteria[ :compiler ].compiled,
|
|
@@ -68,14 +100,16 @@ module DynamicSchema
|
|
|
68
100
|
&block
|
|
69
101
|
)
|
|
70
102
|
else
|
|
71
|
-
if
|
|
72
|
-
unless value_matches_types?( value,
|
|
73
|
-
block.call( IncompatibleTypeError.new( path: path, key: key, type:
|
|
103
|
+
if type && value && !criteria[ :default_assigned ]
|
|
104
|
+
unless value_matches_types?( value, type )
|
|
105
|
+
block.call( IncompatibleTypeError.new( path: path, key: key, type: type, value: value ) )
|
|
74
106
|
end
|
|
75
107
|
end
|
|
76
108
|
end
|
|
77
109
|
else
|
|
78
|
-
if
|
|
110
|
+
if has_multiple_types
|
|
111
|
+
__validate_types_array( Array( value ), criteria, path, key, &block )
|
|
112
|
+
elsif type == Object
|
|
79
113
|
groups = Array( value )
|
|
80
114
|
groups.each do | group |
|
|
81
115
|
traverse_and_validate_values(
|
metadata
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dynamicschema
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kristoph Cichocki-Romanov
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: minitest
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '6.0'
|
|
20
19
|
type: :development
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '6.0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: debug
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -76,7 +75,6 @@ licenses:
|
|
|
76
75
|
metadata:
|
|
77
76
|
source_code_uri: https://github.com/EndlessInternational/dynamic_schema
|
|
78
77
|
bug_tracker_uri: https://github.com/EndlessInternational/dynamic_schema/issues
|
|
79
|
-
post_install_message:
|
|
80
78
|
rdoc_options: []
|
|
81
79
|
require_paths:
|
|
82
80
|
- lib
|
|
@@ -91,8 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
91
89
|
- !ruby/object:Gem::Version
|
|
92
90
|
version: '0'
|
|
93
91
|
requirements: []
|
|
94
|
-
rubygems_version: 3.
|
|
95
|
-
signing_key:
|
|
92
|
+
rubygems_version: 3.6.7
|
|
96
93
|
specification_version: 4
|
|
97
94
|
summary: DynamicSchema is a lightweight and simple yet powerful gem that enables flexible
|
|
98
95
|
semantic schema definitions for constructing and validating complex configurations
|