treaty 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/config/locales/en.yml +11 -0
- data/lib/treaty/attribute/option/modifiers/cast_modifier.rb +244 -0
- data/lib/treaty/attribute/option/modifiers/transform_modifier.rb +111 -0
- data/lib/treaty/attribute/option/registry_initializer.rb +4 -0
- data/lib/treaty/attribute/option_normalizer.rb +2 -1
- data/lib/treaty/attribute/validation/nested_transformer.rb +7 -6
- data/lib/treaty/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 600a422c9ddcdff83b3ec4cde1c8124adb8ae52e1c1d88744d8474bc4afa8c68
|
|
4
|
+
data.tar.gz: dd425b19d451b34f46b07747586f35ba7df4dcac9c554a481ac5dd27e1fe2141
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1739edd5d1c38fe70fc6ab892b06ec15df3a665724df68c95f351675dae4e8c6a00368d65489bbfde0900a67841b9aad1e7eb57f81b948248ae902755f485519
|
|
7
|
+
data.tar.gz: 627d321a706c846e3249afb9e97f4ceb48573af52fcf962459e38316ed76ed7d979c4fd0fcffa8146cff5e7cfeab36b4cf391f9bfb3d7c82ca8de3cd6c5ea439
|
data/config/locales/en.yml
CHANGED
|
@@ -49,6 +49,17 @@ en:
|
|
|
49
49
|
as:
|
|
50
50
|
invalid_type: "Option 'as' for attribute '%{attribute}' must be a Symbol. Got: %{type}"
|
|
51
51
|
|
|
52
|
+
transform:
|
|
53
|
+
invalid_type: "Option 'transform' for attribute '%{attribute}' must be a Proc or Lambda. Got: %{type}"
|
|
54
|
+
execution_error: "Transform failed for attribute '%{attribute}': %{error}"
|
|
55
|
+
|
|
56
|
+
cast:
|
|
57
|
+
invalid_type: "Option 'cast' for attribute '%{attribute}' must be a Symbol. Got: %{type}"
|
|
58
|
+
source_not_supported: "Option 'cast' for attribute '%{attribute}' cannot be used with type '%{source_type}'. Casting is only supported for: %{allowed}"
|
|
59
|
+
target_not_supported: "Option 'cast' for attribute '%{attribute}' cannot cast to '%{target_type}'. Supported target types: %{allowed}"
|
|
60
|
+
conversion_not_supported: "Option 'cast' for attribute '%{attribute}' does not support conversion from '%{from}' to '%{to}'"
|
|
61
|
+
conversion_error: "Cast failed for attribute '%{attribute}' from '%{from}' to '%{to}'. Value: '%{value}'. Error: %{error}"
|
|
62
|
+
|
|
52
63
|
# Attribute builder DSL
|
|
53
64
|
builder:
|
|
54
65
|
not_implemented: "%{class} must implement #create_attribute"
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Treaty
|
|
4
|
+
module Attribute
|
|
5
|
+
module Option
|
|
6
|
+
module Modifiers
|
|
7
|
+
# Converts attribute values between different types automatically.
|
|
8
|
+
#
|
|
9
|
+
# ## Usage Examples
|
|
10
|
+
#
|
|
11
|
+
# Simple mode:
|
|
12
|
+
# string :created_at, cast: :datetime
|
|
13
|
+
# datetime :timestamp, cast: :string
|
|
14
|
+
# integer :active, cast: :boolean
|
|
15
|
+
#
|
|
16
|
+
# Advanced mode with custom error message:
|
|
17
|
+
# string :created_at, cast: {
|
|
18
|
+
# to: :datetime,
|
|
19
|
+
# message: "Invalid date format"
|
|
20
|
+
# }
|
|
21
|
+
#
|
|
22
|
+
# ## Use Cases
|
|
23
|
+
#
|
|
24
|
+
# 1. **Request type conversion**:
|
|
25
|
+
# ```ruby
|
|
26
|
+
# request do
|
|
27
|
+
# string :created_at, cast: :datetime
|
|
28
|
+
# end
|
|
29
|
+
# # Input: { created_at: "2024-01-15T10:30:00Z" }
|
|
30
|
+
# # Service receives: { created_at: DateTime object }
|
|
31
|
+
# ```
|
|
32
|
+
#
|
|
33
|
+
# 2. **Response type conversion**:
|
|
34
|
+
# ```ruby
|
|
35
|
+
# response 200 do
|
|
36
|
+
# datetime :created_at, cast: :string
|
|
37
|
+
# end
|
|
38
|
+
# # Service returns: { created_at: DateTime object }
|
|
39
|
+
# # Output: { created_at: "2024-01-15T10:30:00Z" }
|
|
40
|
+
# ```
|
|
41
|
+
#
|
|
42
|
+
# 3. **Unix timestamp conversion**:
|
|
43
|
+
# ```ruby
|
|
44
|
+
# integer :timestamp, cast: :datetime
|
|
45
|
+
# datetime :created_at, cast: :integer
|
|
46
|
+
# ```
|
|
47
|
+
#
|
|
48
|
+
# ## Supported Conversions
|
|
49
|
+
#
|
|
50
|
+
# ### From Integer
|
|
51
|
+
# - integer -> string: Converts to string representation
|
|
52
|
+
# - integer -> boolean: 0 = false, non-zero = true
|
|
53
|
+
# - integer -> datetime: Treats as Unix timestamp
|
|
54
|
+
#
|
|
55
|
+
# ### From String
|
|
56
|
+
# - string -> integer: Parses integer from string
|
|
57
|
+
# - string -> boolean: Parses truthy/falsy strings (true/false, yes/no, 1/0, on/off)
|
|
58
|
+
# - string -> datetime: Parses datetime string (ISO8601, RFC3339, etc.)
|
|
59
|
+
#
|
|
60
|
+
# ### From Boolean
|
|
61
|
+
# - boolean -> string: Converts to "true" or "false"
|
|
62
|
+
# - boolean -> integer: true = 1, false = 0
|
|
63
|
+
#
|
|
64
|
+
# ### From DateTime
|
|
65
|
+
# - datetime -> string: Converts to ISO8601 format
|
|
66
|
+
# - datetime -> integer: Converts to Unix timestamp
|
|
67
|
+
#
|
|
68
|
+
# ## Important Notes
|
|
69
|
+
#
|
|
70
|
+
# - Cast option only works with scalar types (integer, string, boolean, datetime)
|
|
71
|
+
# - Array and Object types are not supported for casting
|
|
72
|
+
# - Casting to the same type is allowed (no-op)
|
|
73
|
+
# - Nil values are not transformed (handled by RequiredValidator)
|
|
74
|
+
# - All conversion errors are caught and re-raised as Validation errors
|
|
75
|
+
#
|
|
76
|
+
# ## Error Handling
|
|
77
|
+
#
|
|
78
|
+
# If conversion fails (e.g., invalid date string, non-numeric string to integer),
|
|
79
|
+
# the error is caught and converted to a Treaty::Exceptions::Validation error.
|
|
80
|
+
#
|
|
81
|
+
# ## Advanced Mode
|
|
82
|
+
#
|
|
83
|
+
# Schema format: `{ to: :target_type, message: "Custom error" }`
|
|
84
|
+
# Note: Uses `:to` key instead of the default `:is` key.
|
|
85
|
+
class CastModifier < Treaty::Attribute::Option::Base
|
|
86
|
+
# Types that support casting (scalar types only)
|
|
87
|
+
ALLOWED_CAST_TYPES = %i[integer string boolean datetime].freeze
|
|
88
|
+
|
|
89
|
+
# Validates that cast option is correctly configured
|
|
90
|
+
#
|
|
91
|
+
# @raise [Treaty::Exceptions::Validation] If cast configuration is invalid
|
|
92
|
+
# @return [void]
|
|
93
|
+
def validate_schema! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
94
|
+
# If option_schema is nil, cast is not used for this attribute
|
|
95
|
+
return if @option_schema.nil?
|
|
96
|
+
|
|
97
|
+
target_type = option_value
|
|
98
|
+
|
|
99
|
+
# Validate that target type is a Symbol
|
|
100
|
+
unless target_type.is_a?(Symbol)
|
|
101
|
+
raise Treaty::Exceptions::Validation,
|
|
102
|
+
I18n.t(
|
|
103
|
+
"treaty.attributes.modifiers.cast.invalid_type",
|
|
104
|
+
attribute: @attribute_name,
|
|
105
|
+
type: target_type.class
|
|
106
|
+
)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Validate that source type supports casting
|
|
110
|
+
unless ALLOWED_CAST_TYPES.include?(@attribute_type)
|
|
111
|
+
raise Treaty::Exceptions::Validation,
|
|
112
|
+
I18n.t(
|
|
113
|
+
"treaty.attributes.modifiers.cast.source_not_supported",
|
|
114
|
+
attribute: @attribute_name,
|
|
115
|
+
source_type: @attribute_type,
|
|
116
|
+
allowed: ALLOWED_CAST_TYPES.join(", ")
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Validate that target type is allowed
|
|
121
|
+
unless ALLOWED_CAST_TYPES.include?(target_type)
|
|
122
|
+
raise Treaty::Exceptions::Validation,
|
|
123
|
+
I18n.t(
|
|
124
|
+
"treaty.attributes.modifiers.cast.target_not_supported",
|
|
125
|
+
attribute: @attribute_name,
|
|
126
|
+
target_type:,
|
|
127
|
+
allowed: ALLOWED_CAST_TYPES.join(", ")
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Validate that conversion from source to target is supported
|
|
132
|
+
return if conversion_supported?(@attribute_type, target_type)
|
|
133
|
+
|
|
134
|
+
raise Treaty::Exceptions::Validation,
|
|
135
|
+
I18n.t(
|
|
136
|
+
"treaty.attributes.modifiers.cast.conversion_not_supported",
|
|
137
|
+
attribute: @attribute_name,
|
|
138
|
+
from: @attribute_type,
|
|
139
|
+
to: target_type
|
|
140
|
+
)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Applies type conversion to the value
|
|
144
|
+
# Skips conversion for nil values (handled by RequiredValidator)
|
|
145
|
+
#
|
|
146
|
+
# @param value [Object] The current value
|
|
147
|
+
# @return [Object] Converted value
|
|
148
|
+
def transform_value(value) # rubocop:disable Metrics/MethodLength
|
|
149
|
+
return value if value.nil? # Cast doesn't modify nil, required validator handles it.
|
|
150
|
+
|
|
151
|
+
target_type = option_value
|
|
152
|
+
conversion_lambda = conversion_matrix.dig(@attribute_type, target_type)
|
|
153
|
+
|
|
154
|
+
# Call conversion lambda
|
|
155
|
+
conversion_lambda.call(value:)
|
|
156
|
+
rescue StandardError => e
|
|
157
|
+
attributes = {
|
|
158
|
+
attribute: @attribute_name,
|
|
159
|
+
from: @attribute_type,
|
|
160
|
+
to: target_type,
|
|
161
|
+
value:,
|
|
162
|
+
error: e.message
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Catch all exceptions from conversion execution
|
|
166
|
+
error_message = resolve_custom_message(**attributes) || I18n.t(
|
|
167
|
+
"treaty.attributes.modifiers.cast.conversion_error",
|
|
168
|
+
**attributes
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
raise Treaty::Exceptions::Validation, error_message
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
protected
|
|
175
|
+
|
|
176
|
+
# Override value_key to use :to instead of :is
|
|
177
|
+
# This makes advanced mode syntax: cast: { to: :datetime }
|
|
178
|
+
#
|
|
179
|
+
# @return [Symbol] The key :to
|
|
180
|
+
def value_key
|
|
181
|
+
:to
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
# Checks if conversion from source type to target type is supported
|
|
187
|
+
#
|
|
188
|
+
# @param from_type [Symbol] Source type
|
|
189
|
+
# @param to_type [Symbol] Target type
|
|
190
|
+
# @return [Boolean] True if conversion is supported
|
|
191
|
+
def conversion_supported?(from_type, to_type)
|
|
192
|
+
conversion_matrix.dig(from_type, to_type).present?
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Matrix of all supported type conversions
|
|
196
|
+
# Maps from_type => to_type => conversion_lambda
|
|
197
|
+
#
|
|
198
|
+
# @return [Hash] Conversion matrix
|
|
199
|
+
def conversion_matrix # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
200
|
+
@conversion_matrix ||= {
|
|
201
|
+
integer: {
|
|
202
|
+
integer: ->(value:) { value }, # No-op for same type
|
|
203
|
+
string: ->(value:) { value.to_s },
|
|
204
|
+
boolean: ->(value:) { value != 0 },
|
|
205
|
+
datetime: ->(value:) { Time.at(value) }
|
|
206
|
+
},
|
|
207
|
+
string: {
|
|
208
|
+
string: ->(value:) { value }, # No-op for same type
|
|
209
|
+
integer: ->(value:) { Integer(value) },
|
|
210
|
+
boolean: ->(value:) { parse_boolean(value) },
|
|
211
|
+
datetime: ->(value:) { DateTime.parse(value) }
|
|
212
|
+
},
|
|
213
|
+
boolean: {
|
|
214
|
+
boolean: ->(value:) { value }, # No-op for same type
|
|
215
|
+
string: ->(value:) { value.to_s },
|
|
216
|
+
integer: ->(value:) { value ? 1 : 0 }
|
|
217
|
+
},
|
|
218
|
+
datetime: {
|
|
219
|
+
datetime: ->(value:) { value }, # No-op for same type
|
|
220
|
+
string: ->(value:) { value.iso8601 },
|
|
221
|
+
integer: ->(value:) { value.to_i }
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Parses a string value into a boolean
|
|
227
|
+
# Recognizes: true/false, yes/no, 1/0, on/off (case-insensitive)
|
|
228
|
+
#
|
|
229
|
+
# @param value [String] The string value to parse
|
|
230
|
+
# @return [Boolean] Parsed boolean value
|
|
231
|
+
# @raise [ArgumentError] If string is not a recognized boolean value
|
|
232
|
+
def parse_boolean(value)
|
|
233
|
+
normalized = value.to_s.downcase.strip
|
|
234
|
+
|
|
235
|
+
return true if %w[true 1 yes on].include?(normalized)
|
|
236
|
+
return false if %w[false 0 no off].include?(normalized)
|
|
237
|
+
|
|
238
|
+
raise ArgumentError, "Cannot convert '#{value}' to boolean"
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Treaty
|
|
4
|
+
module Attribute
|
|
5
|
+
module Option
|
|
6
|
+
module Modifiers
|
|
7
|
+
# Transforms attribute values using custom lambda functions.
|
|
8
|
+
#
|
|
9
|
+
# ## Usage Examples
|
|
10
|
+
#
|
|
11
|
+
# Simple mode:
|
|
12
|
+
# integer :amount, transform: ->(value:) { value * 100 }
|
|
13
|
+
# string :title, transform: ->(value:) { value.strip.upcase }
|
|
14
|
+
#
|
|
15
|
+
# Advanced mode with custom error message:
|
|
16
|
+
# integer :amount, transform: {
|
|
17
|
+
# is: ->(value:) { value * 100 },
|
|
18
|
+
# message: "Failed to transform amount"
|
|
19
|
+
# }
|
|
20
|
+
#
|
|
21
|
+
# ## Use Cases
|
|
22
|
+
#
|
|
23
|
+
# 1. **Request transformation**:
|
|
24
|
+
# ```ruby
|
|
25
|
+
# request do
|
|
26
|
+
# integer :amount_cents, transform: ->(value:) { value * 100 }
|
|
27
|
+
# end
|
|
28
|
+
# # Input: { amount_cents: 10 }
|
|
29
|
+
# # Service receives: { amount_cents: 1000 }
|
|
30
|
+
# ```
|
|
31
|
+
#
|
|
32
|
+
# 2. **Response transformation**:
|
|
33
|
+
# ```ruby
|
|
34
|
+
# response 200 do
|
|
35
|
+
# string :title, transform: ->(value:) { value.titleize }
|
|
36
|
+
# end
|
|
37
|
+
# # Service returns: { title: "hello world" }
|
|
38
|
+
# # Output: { title: "Hello World" }
|
|
39
|
+
# ```
|
|
40
|
+
#
|
|
41
|
+
# 3. **Complex transformations**:
|
|
42
|
+
# ```ruby
|
|
43
|
+
# string :email, transform: ->(value:) { value.downcase.strip }
|
|
44
|
+
# datetime :timestamp, transform: ->(value:) { value.iso8601 }
|
|
45
|
+
# ```
|
|
46
|
+
#
|
|
47
|
+
# ## Important Notes
|
|
48
|
+
#
|
|
49
|
+
# - Lambda must accept named argument `value:`
|
|
50
|
+
# - All exceptions raised in lambda are caught and re-raised as Validation errors
|
|
51
|
+
# - Transformation is applied during Phase 3 (after validation)
|
|
52
|
+
# - Can be combined with other options (required, default, as, etc.)
|
|
53
|
+
#
|
|
54
|
+
# ## Error Handling
|
|
55
|
+
#
|
|
56
|
+
# If the lambda raises any exception, it's caught and converted to a
|
|
57
|
+
# Treaty::Exceptions::Validation with appropriate error message.
|
|
58
|
+
#
|
|
59
|
+
# ## Advanced Mode
|
|
60
|
+
#
|
|
61
|
+
# Schema format: `{ is: lambda, message: nil }`
|
|
62
|
+
class TransformModifier < Treaty::Attribute::Option::Base
|
|
63
|
+
# Validates that transform value is a lambda
|
|
64
|
+
#
|
|
65
|
+
# @raise [Treaty::Exceptions::Validation] If transform is not a Proc/lambda
|
|
66
|
+
# @return [void]
|
|
67
|
+
def validate_schema!
|
|
68
|
+
transform_lambda = option_value
|
|
69
|
+
|
|
70
|
+
return if transform_lambda.respond_to?(:call)
|
|
71
|
+
|
|
72
|
+
raise Treaty::Exceptions::Validation,
|
|
73
|
+
I18n.t(
|
|
74
|
+
"treaty.attributes.modifiers.transform.invalid_type",
|
|
75
|
+
attribute: @attribute_name,
|
|
76
|
+
type: transform_lambda.class
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Applies transformation to the value using the provided lambda
|
|
81
|
+
# Catches all exceptions and re-raises as Validation errors
|
|
82
|
+
# Skips transformation for nil values (handled by RequiredValidator)
|
|
83
|
+
#
|
|
84
|
+
# @param value [Object] The current value
|
|
85
|
+
# @return [Object] Transformed value
|
|
86
|
+
def transform_value(value) # rubocop:disable Metrics/MethodLength
|
|
87
|
+
return value if value.nil? # Transform doesn't modify nil, required validator handles it.
|
|
88
|
+
|
|
89
|
+
transform_lambda = option_value
|
|
90
|
+
|
|
91
|
+
# Call lambda with named argument
|
|
92
|
+
transform_lambda.call(value:)
|
|
93
|
+
rescue StandardError => e
|
|
94
|
+
attributes = {
|
|
95
|
+
attribute: @attribute_name,
|
|
96
|
+
error: e.message
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
# Catch all exceptions from lambda execution
|
|
100
|
+
error_message = resolve_custom_message(**attributes) || I18n.t(
|
|
101
|
+
"treaty.attributes.modifiers.transform.execution_error",
|
|
102
|
+
**attributes
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
raise Treaty::Exceptions::Validation, error_message
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -27,6 +27,8 @@ module Treaty
|
|
|
27
27
|
#
|
|
28
28
|
# - `:as` → AsModifier - Renames attributes
|
|
29
29
|
# - `:default` → DefaultModifier - Provides default values
|
|
30
|
+
# - `:transform` → TransformModifier - Transforms values using custom lambdas
|
|
31
|
+
# - `:cast` → CastModifier - Converts values between types automatically
|
|
30
32
|
#
|
|
31
33
|
# ## Auto-Registration
|
|
32
34
|
#
|
|
@@ -81,6 +83,8 @@ module Treaty
|
|
|
81
83
|
def register_modifiers!
|
|
82
84
|
Registry.register(:as, Modifiers::AsModifier, category: :modifier)
|
|
83
85
|
Registry.register(:default, Modifiers::DefaultModifier, category: :modifier)
|
|
86
|
+
Registry.register(:transform, Modifiers::TransformModifier, category: :modifier)
|
|
87
|
+
Registry.register(:cast, Modifiers::CastModifier, category: :modifier)
|
|
84
88
|
end
|
|
85
89
|
end
|
|
86
90
|
end
|
|
@@ -70,7 +70,8 @@ module Treaty
|
|
|
70
70
|
OPTION_KEY_MAPPING = {
|
|
71
71
|
in: { advanced_key: :inclusion, value_key: :in },
|
|
72
72
|
as: { advanced_key: :as, value_key: :is },
|
|
73
|
-
default: { advanced_key: :default, value_key: :is }
|
|
73
|
+
default: { advanced_key: :default, value_key: :is },
|
|
74
|
+
cast: { advanced_key: :cast, value_key: :to }
|
|
74
75
|
}.freeze
|
|
75
76
|
private_constant :OPTION_KEY_MAPPING
|
|
76
77
|
|
|
@@ -138,8 +138,7 @@ module Treaty
|
|
|
138
138
|
def transform(value)
|
|
139
139
|
value.each_with_index.map do |item, index|
|
|
140
140
|
if simple_array?
|
|
141
|
-
|
|
142
|
-
item
|
|
141
|
+
transform_simple_element(item, index)
|
|
143
142
|
else
|
|
144
143
|
transform_array_item(item, index)
|
|
145
144
|
end
|
|
@@ -156,19 +155,21 @@ module Treaty
|
|
|
156
155
|
attribute.collection_of_attributes.first.name == SELF_OBJECT
|
|
157
156
|
end
|
|
158
157
|
|
|
159
|
-
#
|
|
158
|
+
# Transforms a simple array element (primitive value)
|
|
159
|
+
# Validates and applies transformations to the element
|
|
160
160
|
#
|
|
161
|
-
# @param item [Object] Array element to
|
|
161
|
+
# @param item [Object] Array element to transform
|
|
162
162
|
# @param index [Integer] Element index for error messages
|
|
163
163
|
# @raise [Treaty::Exceptions::Validation] If validation fails
|
|
164
|
-
# @return [
|
|
165
|
-
def
|
|
164
|
+
# @return [Object] Transformed element value
|
|
165
|
+
def transform_simple_element(item, index) # rubocop:disable Metrics/MethodLength
|
|
166
166
|
self_attr = attribute.collection_of_attributes.first
|
|
167
167
|
validator = AttributeValidator.new(self_attr)
|
|
168
168
|
validator.validate_schema!
|
|
169
169
|
|
|
170
170
|
begin
|
|
171
171
|
validator.validate_value!(item)
|
|
172
|
+
validator.transform_value(item)
|
|
172
173
|
rescue Treaty::Exceptions::Validation => e
|
|
173
174
|
raise Treaty::Exceptions::Validation,
|
|
174
175
|
I18n.t(
|
data/lib/treaty/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: treaty
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anton Sokolov
|
|
@@ -156,7 +156,9 @@ files:
|
|
|
156
156
|
- lib/treaty/attribute/helper_mapper.rb
|
|
157
157
|
- lib/treaty/attribute/option/base.rb
|
|
158
158
|
- lib/treaty/attribute/option/modifiers/as_modifier.rb
|
|
159
|
+
- lib/treaty/attribute/option/modifiers/cast_modifier.rb
|
|
159
160
|
- lib/treaty/attribute/option/modifiers/default_modifier.rb
|
|
161
|
+
- lib/treaty/attribute/option/modifiers/transform_modifier.rb
|
|
160
162
|
- lib/treaty/attribute/option/registry.rb
|
|
161
163
|
- lib/treaty/attribute/option/registry_initializer.rb
|
|
162
164
|
- lib/treaty/attribute/option/validators/format_validator.rb
|