plumb 0.0.17 → 0.0.18

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24a6b9a58d29c5aa9e443586d0d529aaf79fcf91a5ee724366d9153174c73fa9
4
- data.tar.gz: c6200d6bc762aecf985e359c5326c6014003950f998406dabbfaa9c7aca8fc10
3
+ metadata.gz: c718a272ada163dfc399bd4a6ae0353ac95b99210ac5450e5adf5e77881ed2d5
4
+ data.tar.gz: 2721e793e2cba293fcf8859d6b1ff960b7bc5e0ae33cf4374aa09a7532c6724b
5
5
  SHA512:
6
- metadata.gz: d683a2a89fc717f406efcc16b884cafa10dafa148be86ffc1810a377b4f065e1e40e0d21719fe70752e67d5c4eef86843076fa9ffd1513a2d345f666b705577f
7
- data.tar.gz: 5788b7b83dfb2c342a9c59f1080b30e3db93f9ff7b3c3f6eda0060021275ae648406559bb9bbee96fe204463a3715571e7e042401771e98c9836f5d5306a4087
6
+ metadata.gz: c1ab0c74145b108e9b23503fe701a7237defcd72a463d05aa9500da2db1835559b279e3a0199c68774285000012b400d04026636dfbe21e53ee1872058bf7aed
7
+ data.tar.gz: fb65d7c1ebd803e08137a4473260a7050ec8025311696742ae8762b4b1fea77327ce5059a9b08a28c1ea78d3a9d8851378152c6b7f33d7489bc628f4375e2b9c
@@ -65,7 +65,7 @@ module Plumb
65
65
  # Steps might return the same result instance, so we map the values directly
66
66
  # separate from the errors.
67
67
  element_result = result.dup
68
- errors = {}
68
+ errors = Hash.new(capacity: result.value.size)
69
69
  values = result.value.map.with_index do |e, idx|
70
70
  re = element_type.call(element_result.reset(e))
71
71
  errors[idx] = re.errors unless re.valid?
@@ -228,12 +228,14 @@ module Plumb
228
228
  super
229
229
  end
230
230
 
231
+ MUST_BE_HASH = ['Must be a Hash of attributes'].freeze
232
+
231
233
  # The Plumb::Step interface
232
234
  # @param result [Plumb::Result::Valid]
233
235
  # @return [Plumb::Result::Valid, Plumb::Result::Invalid]
234
236
  def call(result)
235
237
  return result if result.value.is_a?(self)
236
- return result.invalid(errors: ['Must be a Hash of attributes']) unless result.value.respond_to?(:to_h)
238
+ return result.invalid(errors: MUST_BE_HASH) unless result.value.respond_to?(:to_h)
237
239
 
238
240
  instance = new(result.value.to_h)
239
241
  instance.valid? ? result.valid(instance) : result.invalid(instance, errors: instance.errors.to_h)
@@ -295,6 +295,18 @@ module Plumb
295
295
  end
296
296
 
297
297
  def call(result) = type.call(result)
298
+
299
+ # Two nodes are equal when they wrap the same type with the same
300
+ # node_name and args. The default Composable#== compares #children,
301
+ # but a Node holds its identity in @node_name/@type/@args, so without
302
+ # this every as_node-wrapped type (Email, Boolean, etc.) would compare
303
+ # equal to every other.
304
+ def ==(other)
305
+ other.is_a?(self.class) &&
306
+ other.node_name == node_name &&
307
+ other.type == type &&
308
+ other.args == args
309
+ end
298
310
  end
299
311
 
300
312
  # Wrap a Step in a node with a custom #node_name
@@ -108,24 +108,30 @@ module Plumb
108
108
  return result unless _schema.any?
109
109
 
110
110
  input = result.value
111
- errors = {}
112
- field_result = result.dup
113
- initial = {}
114
- initial = initial.merge(input) if @inclusive
115
- output = _schema.each.with_object(initial) do |(key, field), ret|
111
+ errors = nil # Do not allocate errors unless needed
112
+ output = @inclusive ? input.dup : {}
113
+ field_result = Result.valid(nil)
114
+
115
+ _schema.each do |key, field|
116
116
  key_s = key.to_key
117
117
  if input.key?(key_s)
118
118
  r = field.call(field_result.reset(input[key_s]))
119
- errors[key_s] = r.errors unless r.valid?
120
- ret[key_s] = r.value
119
+ output[key_s] = r.value
120
+ unless r.valid?
121
+ errors ||= {}
122
+ errors[key_s] = r.errors
123
+ end
121
124
  elsif !key.optional?
122
125
  r = field.call(BLANK_RESULT)
123
- errors[key_s] = r.errors unless r.valid?
124
- ret[key_s] = r.value unless r.value == Undefined
126
+ output[key_s] = r.value unless r.value == Undefined
127
+ unless r.valid?
128
+ errors ||= {}
129
+ errors[key_s] = r.errors
130
+ end
125
131
  end
126
132
  end
127
133
 
128
- errors.any? ? result.invalid(output, errors:) : result.valid(output)
134
+ errors ? result.invalid(output, errors:) : result.valid(output)
129
135
  end
130
136
 
131
137
  def ==(other)
@@ -59,7 +59,7 @@ module Plumb
59
59
  def call(result)
60
60
  obj = result.value
61
61
  missing_methods = @method_names.reject { |m| obj.respond_to?(m) }
62
- return result.invalid(errors: "missing methods: #{missing_methods.join(', ')}") if missing_methods.any?
62
+ return result.invalid(errors: "Invalid #{self.name}. Missing methods: #{missing_methods.join(', ')}") if missing_methods.any?
63
63
 
64
64
  result
65
65
  end
data/lib/plumb/or.rb CHANGED
@@ -27,8 +27,13 @@ module Plumb
27
27
  if right_result.valid?
28
28
  right_result
29
29
  else
30
- right_result.invalid(errors: [left_result.errors,
31
- right_result.errors].flatten)
30
+ # Decrease Array allocations slightly
31
+ # OR can be really expensive in composite ORed types
32
+ left_errors = left_result.errors.is_a?(Array) ? left_result.errors : [left_result.errors]
33
+ right_errors = right_result.errors.is_a?(Array) ? right_result.errors.first : right_result.errors
34
+ left_errors << right_errors
35
+
36
+ right_result.invalid(errors: left_errors)
32
37
  end
33
38
  end
34
39
  end
data/lib/plumb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plumb
4
- VERSION = '0.0.17'
4
+ VERSION = '0.0.18'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plumb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.17
4
+ version: 0.0.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  requirements: []
118
- rubygems_version: 3.6.9
118
+ rubygems_version: 4.0.8
119
119
  specification_version: 4
120
120
  summary: Data validation and transformation library.
121
121
  test_files: []