# frozen_string_literal: true module Tesseract module Transaction module Steps # Adds a "merge" step that expects the input to the step to be a hash, # and then merges the successful result of the step into the input hash. # If the step results in a Failure then that Failure is returned instead. # # If the return value of the step is not a hash, then the return value is # merged into the input hash using the step name as the key. # # Usage: # # merge :user # merge :lookup_metadata # # # input: { user_id: 42, name: "Chuck" } # def user(user_id:, **) # User.find(user_id) # end # # output: { user_id: 42, name: "Chuck", user: # } # # def lookup_metadata(user:,.**) # resp = APIClient.get_email(user.client_id) # { email: resp["user_email"], fists: resp["fists"]["items"].size } # end # # # output: { user_id: 42, name: "Chuck", user: #, email: "chuck@example", fists: 2 } # module Merge class MergeStepAdapter < Dry::Transaction::StepAdapters include Dry::Monads::Result::Mixin def call(operation, _options, input) result = operation.call(input[0]) return result if result.try(:failure?) value = result.try(:value!) || result || {} value = { operation.operation.name => value } unless value.is_a?(Hash) Success(input[0].merge(value)) end end Dry::Transaction::StepAdapters.register(:merge, MergeStepAdapter.new) unless Dry::Transaction::StepAdapters.key?(:merge) end end end end