Class: SorbetOperation::Result
- Inherits:
-
Object
- Object
- SorbetOperation::Result
- Extended by:
- T::Generic, T::Sig
- Defined in:
- lib/sorbet_operation/result.rb
Overview
Constant Summary collapse
- ValueType =
The type of the value wrapped by the SorbetOperation::Result. The type can be any valid Sorbet type, as long as it's a subtype of
Object. type_member { { upper: Object } }
Instance Method Summary collapse
- #casted_value ⇒ Object private
- #failure? ⇒ Boolean
-
#initialize(success, value, error) ⇒ Result
constructor
A new instance of Result.
- #on_failure {|T.must(@error)| ... } ⇒ Object
- #on_success {|casted_value| ... } ⇒ Object
- #safe_unwrap ⇒ Object
- #safe_unwrap_error ⇒ Object
- #success? ⇒ Boolean
- #unwrap! ⇒ Object
- #unwrap_error! ⇒ Object
- #unwrap_or(default) ⇒ Object
- #unwrap_or_else {|T.must(@error)| ... } ⇒ Object
Constructor Details
#initialize(success, value, error) ⇒ Result
Returns a new instance of Result.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/sorbet_operation/result.rb', line 36 def initialize(success, value, error) @success = success @value = value @error = error # NOTE: these checks are annoying. A better API would be to make this # constructor private and provide two factory methods: # - `Result.success(value)` # - `Result.failure(error)` # # However, in order to do this, we would need to be able to use # {ValueType} in class methods. At this time, there is no way to tell # Sorbet that a generic type applies to both the class and its # singleton. We would need to duplicate the value type: # ``` # ValueTypeMember = type_member { { upper: Object } } # ValueTypeTemplate = type_template { { upper: Object } } # ``` # and every subclass would need to specify both (and ensure that # they're both set to the same type). This would be quite clumsy. Since # `Result` should rarely be instantiated directly (rather, it's # instantiated by `SorbetOperation::Base#perform`), we'll just live with # this less than ideal API for now. if @success # We can't test that value is not nil because the value type can be # nilable. (In theory we could check if the type is nilable and only # apply the check if it's not, but that's not worth the complexity.) unless error.nil? raise ArgumentError, "Cannot pass an error to a success result" end elsif error.nil? raise ArgumentError, "Must pass an error to a failure result" elsif !value.nil? raise ArgumentError, "Cannot pass a value to a failure result" end end |
Instance Method Details
#casted_value ⇒ Object (private)
198 199 200 |
# File 'lib/sorbet_operation/result.rb', line 198 def casted_value T.cast(@value, ValueType) end |
#failure? ⇒ Boolean
81 82 83 |
# File 'lib/sorbet_operation/result.rb', line 81 def failure? !success? end |
#on_failure {|T.must(@error)| ... } ⇒ Object
173 174 175 176 |
# File 'lib/sorbet_operation/result.rb', line 173 def on_failure(&blk) yield(T.must(@error)) if failure? self end |
#on_success {|casted_value| ... } ⇒ Object
160 161 162 163 |
# File 'lib/sorbet_operation/result.rb', line 160 def on_success(&blk) yield(casted_value) if success? self end |
#safe_unwrap ⇒ Object
97 98 99 100 101 |
# File 'lib/sorbet_operation/result.rb', line 97 def safe_unwrap return if failure? casted_value end |
#safe_unwrap_error ⇒ Object
146 147 148 149 150 |
# File 'lib/sorbet_operation/result.rb', line 146 def safe_unwrap_error return T.must(@error) if failure? nil end |
#success? ⇒ Boolean
75 76 77 |
# File 'lib/sorbet_operation/result.rb', line 75 def success? @success end |
#unwrap! ⇒ Object
88 89 90 91 92 |
# File 'lib/sorbet_operation/result.rb', line 88 def unwrap! raise T.must(@error) if failure? casted_value end |
#unwrap_error! ⇒ Object
136 137 138 139 140 141 |
# File 'lib/sorbet_operation/result.rb', line 136 def unwrap_error! return T.must(@error) if failure? # TODO: custom error type? raise "Called `unwrap_err!` on a success" end |
#unwrap_or(default) ⇒ Object
112 113 114 115 116 |
# File 'lib/sorbet_operation/result.rb', line 112 def unwrap_or(default) return casted_value if success? default end |
#unwrap_or_else {|T.must(@error)| ... } ⇒ Object
127 128 129 130 131 |
# File 'lib/sorbet_operation/result.rb', line 127 def unwrap_or_else(&blk) return casted_value if success? yield(T.must(@error)) end |