dry-rb / dry-schema

Coercion and validation for data structures
https://dry-rb.org/gems/dry-schema
MIT License
425 stars 110 forks source link

Handle non-Hash to Hash transformation in `before(:key_coercer)` #362

Closed ojab closed 3 years ago

ojab commented 3 years ago

Extract from #353. Fixes #350

Instead of passing only part of the output to the scoped results we're passing whole output and path as a scope, this was result can replace scoped value without any assumptions on the initial and replacement types.

Performance for the common case (steps execution only on the outer schema) is not affected, running benchmarks/params_valid_vs_invalid.rb (10 times each because of the noise) Before:

       valid input 8:    32011.2 i/s
       valid input 0:    31832.2 i/s - same-ish: difference falls within error
       valid input 7:    31779.7 i/s - same-ish: difference falls within error
       valid input 1:    31690.8 i/s - same-ish: difference falls within error
       valid input 2:    31623.7 i/s - same-ish: difference falls within error
       valid input 4:    31438.5 i/s - same-ish: difference falls within error
       valid input 6:    31369.0 i/s - same-ish: difference falls within error
       valid input 5:    31180.7 i/s - same-ish: difference falls within error
       valid input 3:    31118.2 i/s - same-ish: difference falls within error
       valid input 9:    30681.5 i/s - same-ish: difference falls within error
     invalid input 9:    20153.8 i/s - 1.59x  (± 0.00) slower
     invalid input 8:    20103.2 i/s - 1.59x  (± 0.00) slower
     invalid input 7:    20067.7 i/s - 1.60x  (± 0.00) slower
     invalid input 1:    19941.1 i/s - 1.61x  (± 0.00) slower
     invalid input 2:    19937.2 i/s - 1.61x  (± 0.00) slower
     invalid input 3:    19563.4 i/s - 1.64x  (± 0.00) slower
     invalid input 0:    19548.0 i/s - 1.64x  (± 0.00) slower
     invalid input 6:    19313.2 i/s - 1.66x  (± 0.00) slower
     invalid input 5:    18576.3 i/s - 1.72x  (± 0.00) slower
     invalid input 4:    17281.0 i/s - 1.85x  (± 0.00) slower

After:

Comparison:
       valid input 0:    32465.3 i/s
       valid input 2:    32141.4 i/s - same-ish: difference falls within error
       valid input 3:    31842.5 i/s - same-ish: difference falls within error
       valid input 5:    31600.6 i/s - same-ish: difference falls within error
       valid input 6:    31525.6 i/s - same-ish: difference falls within error
       valid input 4:    31306.8 i/s - same-ish: difference falls within error
       valid input 7:    31173.7 i/s - same-ish: difference falls within error
       valid input 8:    31123.6 i/s - same-ish: difference falls within error
       valid input 9:    30858.5 i/s - same-ish: difference falls within error
       valid input 1:    30832.5 i/s - same-ish: difference falls within error
     invalid input 5:    20427.4 i/s - 1.59x  (± 0.00) slower
     invalid input 4:    20413.8 i/s - 1.59x  (± 0.00) slower
     invalid input 6:    20385.7 i/s - 1.59x  (± 0.00) slower
     invalid input 7:    20368.8 i/s - 1.59x  (± 0.00) slower
     invalid input 9:    20276.1 i/s - 1.60x  (± 0.00) slower
     invalid input 8:    20184.7 i/s - 1.61x  (± 0.00) slower
     invalid input 1:    20084.0 i/s - 1.62x  (± 0.00) slower
     invalid input 2:    20078.9 i/s - 1.62x  (± 0.00) slower
     invalid input 3:    19898.7 i/s - 1.63x  (± 0.00) slower
     invalid input 0:    19893.5 i/s - 1.63x  (± 0.00) slower

dry-v specs are passing, didn't measured performance of the nested steps.