lib/safe_operation.rb in safe_operation-1.0.0 vs lib/safe_operation.rb in safe_operation-2.0.0

- old
+ new

@@ -1,24 +1,66 @@ # frozen_string_literal: true +require "forwardable" require_relative "safe_operation/version" require_relative "safe_operation/success" require_relative "safe_operation/failure" -module SafeOperation - NoFailureHandler = Class.new NotImplementedError +class SafeOperation + extend Forwardable - def self.either(maybe_block) - raise NoFailureHandler if !block_given? + class << self + protected(:new) - if maybe = maybe_block.call - Success.new maybe + def run + success(yield) + rescue StandardError => exception + failure(exception) + end + + def success(value) + new(success: value) + end + + def failure(value) + new(failure: value) + end + end + + def_delegators :@result, :success?, :value + + def initialize(success: nil, failure: nil) + @result = success ? Success.new(success) : Failure.new(failure) + end + + def value_or(fallback_value) + if success? + value else - Failure.new yield + fallback_value end - rescue StandardError - Failure.new yield end - NO_FAILURE_HANDLER_MESSAGE = "Please pass in a block to handle the failure 😅" - private_constant :NO_FAILURE_HANDLER_MESSAGE + def value_or_else(&fallback_block) + if success? + value + else + fallback_block.call(value) + end + end + + def and_then(&block) + if success? + self.class.success(block.call(value)) + else + self + end + end + + def or_else(&block) + if success? + self + else + self.class.failure(block.call(value)) + end + end end