Class: Serviced::Result

Inherits:
Object
  • Object
show all
Defined in:
lib/serviced/result.rb

Overview

Outcome of a service or flow. Abstract: instances are always either a Success or a Failure. Results are frozen and therefore immutable.

Consume a result through predicates, callbacks, railway chaining, or pattern matching:

result = CreatePatient.call(name: "Ada", age: 36)

result.success?                 # => true / false
result.value                    # success payload (nil on failure)

result
.on_success { |patient| render json: patient }
.on_failure { |failure| render json: { error: failure.message } }

case result
in Serviced::Success(value:)      then value
in Serviced::Failure(reason:)     then reason
end

Direct Known Subclasses

Failure, Success

Instance Method Summary collapse

Instance Method Details

#and_then {|value| ... } ⇒ Serviced::Result

Railway-oriented chaining: runs the block only on success and returns the Result it produces; short-circuits (returns self) on failure. The block must return a Serviced::Result.

Yield Parameters:

  • value (Object)

    the success payload

Returns:



64
65
66
67
68
69
70
71
72
73
# File 'lib/serviced/result.rb', line 64

def and_then
  return self unless success?

  result = yield(value)
  unless result.is_a?(Result)
    raise ResultTypeError, "#and_then block must return a Serviced::Result, got #{result.class}"
  end

  result
end

#failure?Boolean

Returns whether the operation failed.

Returns:

  • (Boolean)

    whether the operation failed.



31
32
33
# File 'lib/serviced/result.rb', line 31

def failure?
  !success?
end

#map {|value| ... } ⇒ Serviced::Result

Transforms a success value into a new Success; leaves a failure untouched.

Yield Parameters:

  • value (Object)

    the success payload

Returns:



78
79
80
81
82
# File 'lib/serviced/result.rb', line 78

def map
  return self unless success?

  Success.new(yield(value))
end

#on_failure {|failure| ... } ⇒ Serviced::Result

Runs the block with the failure when failed. Returns self so calls can be chained with #on_success.

Yield Parameters:

Returns:



54
55
56
57
# File 'lib/serviced/result.rb', line 54

def on_failure
  yield(self) if failure? && block_given?
  self
end

#on_success {|value| ... } ⇒ Serviced::Result

Runs the block with the success value when successful. Returns self so calls can be chained with #on_failure.

Yield Parameters:

  • value (Object)

    the success payload

Returns:



45
46
47
48
# File 'lib/serviced/result.rb', line 45

def on_success
  yield(value) if success? && block_given?
  self
end

#success?Boolean

Returns whether the operation succeeded.

Returns:

  • (Boolean)

    whether the operation succeeded.

Raises:

  • (NotImplementedError)


26
27
28
# File 'lib/serviced/result.rb', line 26

def success?
  raise NotImplementedError, "#{self.class} must implement #success?"
end

#valueObject?

The success payload. Always nil for a failure.

Returns:

  • (Object, nil)


37
38
39
# File 'lib/serviced/result.rb', line 37

def value
  nil
end