lib/upgrow/result.rb in upgrow-0.0.2 vs lib/upgrow/result.rb in upgrow-0.0.3

- old
+ new

@@ -1,6 +1,9 @@ # frozen_string_literal: true + +require_relative 'immutable_struct' + module Upgrow # Results are special Structs that are generated dynamically to accommodate a # set of pre-defined members. Since different Actions might want to return # zero to multiple values, they are always returned as members of a Result # instance. @@ -24,71 +27,31 @@ # @param members [Array<Symbol>] the list of members the new Result should # be able to hold. # # @return [Result] the new Result class with the given members. def new(*members) - super(*members, :errors) + members << :errors unless members.include?(:errors) + super(*members) end - - # Returns a new Result instance populated with the given values. - # - # @param values [Hash<Symbol, Object>] the list of values for each member - # provided as keyword arguments. - # - # @return [Result] the Result instance populated with the given values. - def success(*values) - new(*values) - end - - # Returns a new Result instance populated with the given errors. - # - # @param errors [ActiveModel::Errors] the errors object to be set as the - # Result errors. - # - # @return [Result] the Result instance populated with the given errors. - def failure(errors) - values = members.to_h { |member| [member, nil] } - new(**values.merge(errors: errors)) - end end - # Calls the given block only when the Result is successful. + # Returns a new Result instance populated with the given values. # - # This method receives a block that is called with the Result values passed - # to the block only when the Result itself is a success, meaning its list of - # errors is empty. Otherwise the block is not called. + # @param values [Hash<Symbol, Object>] the list of values for each member + # provided as keyword arguments. # - # It returns self for convenience so other methods can be chained together. - # - # @yield [values] gives the Result values to the block on a successful - # Result. - # - # @return [Result] self for chaining. - def and_then - yield(**to_h.except(:errors)) if errors.none? - self + # @return [Result] the Result instance populated with the given values. + def initialize(**values) + errors = values.fetch(:errors, []) + super(**values.merge(errors: errors)) end - # Calls the given block only when the Result is a failure. + # Check if the Result is successful or not. A successful Result means there + # are no errors present. # - # This method receives a block that is called with the Result errors passed - # to the block only when the Result itself is a failure, meaning its list of - # errors is not empty. Otherwise the block is not called. - # - # It returns self for convenience so other methods can be chained together. - # - # @yield [errors] gives the Result errors to the block on a failed Result. - # - # @return [Result] self for chaining. - def or_else - yield(errors) if errors.any? - self - end - - private - - def initialize(*args) - values = { errors: [] }.merge(args.first || {}) - super(**values) + # @return [true] if the Result is successful. + # @return [false] if the Result is a failure. + def success? + errors.none? end end end