result: add `expect` helper (#23)
* result: add `expect` helper * result: use explicit conversion in mapConvert
This commit is contained in:
parent
d622c07a08
commit
7287fffebe
|
@ -12,6 +12,8 @@ type
|
|||
## Note: If error is of exception type, it will be raised instead!
|
||||
error*: E
|
||||
|
||||
ResultDefect* = object of Defect
|
||||
|
||||
Result*[T, E] = object
|
||||
## Result type that can hold either a value or an error, but not both
|
||||
##
|
||||
|
@ -232,9 +234,9 @@ func mapErr*[T: not void, E, A](
|
|||
|
||||
func mapConvert*[T0, E0](
|
||||
self: Result[T0, E0], T1: type): Result[T1, E0] {.inline.} =
|
||||
## Convert result value to A using an implicit conversion
|
||||
## Would be nice if it was automatic...
|
||||
if self.isOk: result.ok(self.v)
|
||||
## Convert result value to A using an conversion
|
||||
# Would be nice if it was automatic...
|
||||
if self.isOk: result.ok(T1(self.v))
|
||||
else: result.err(self.e)
|
||||
|
||||
func mapCast*[T0, E0](
|
||||
|
@ -342,6 +344,25 @@ template unsafeGet*[T, E](self: Result[T, E]): T =
|
|||
|
||||
self.v
|
||||
|
||||
func expect*[T: not void, E](self: Result[T, E], m: string): T =
|
||||
## Return value of Result, or raise a `Defect` with the given message - use
|
||||
## this helper to extract the value when an error is not expected, for example
|
||||
## because the program logic dictates that the operation should never fail
|
||||
##
|
||||
## ```nim
|
||||
## let r = Result[int, int].ok(42)
|
||||
## # Put here a helpful comment why you think this won't fail
|
||||
## echo r.expect("r was just set to ok(42)")
|
||||
## ```
|
||||
if not self.isOk():
|
||||
raise (ref ResultDefect)(msg: m)
|
||||
self.v
|
||||
|
||||
func expect*[T: not void, E](self: var Result[T, E], m: string): var T =
|
||||
if not self.isOk():
|
||||
raise (ref ResultDefect)(msg: m)
|
||||
self.v
|
||||
|
||||
func `$`*(self: Result): string =
|
||||
## Returns string representation of `self`
|
||||
if self.isOk: "Ok(" & $self.v & ")"
|
||||
|
@ -416,6 +437,10 @@ template unsafeGet*[E](self: Result[void, E]) =
|
|||
## See also: Option.unsafeGet
|
||||
assert not self.isErr
|
||||
|
||||
func expect*[E](self: Result[void, E], msg: string) =
|
||||
if not self.isOk():
|
||||
raise (ref ResultDefect)(msg: msg)
|
||||
|
||||
func `$`*[E](self: Result[void, E]): string =
|
||||
## Returns string representation of `self`
|
||||
if self.isOk: "Ok()"
|
||||
|
|
|
@ -107,6 +107,7 @@ doAssert $rOk == "Ok(42)"
|
|||
|
||||
doAssert rOk.mapConvert(int64)[] == int64(42)
|
||||
doAssert rOk.mapCast(int8)[] == int8(42)
|
||||
doAssert rOk.mapConvert(uint64)[] == uint64(42)
|
||||
|
||||
# TODO there's a bunch of operators that one could lift through magic - this
|
||||
# is mainly an example
|
||||
|
@ -147,6 +148,8 @@ func testErr(): Result[int, string] =
|
|||
doAssert testOk()[] == 42
|
||||
doAssert testErr().error == "323"
|
||||
|
||||
doAssert testOk().expect("testOk never fails") == 42
|
||||
|
||||
func testQn(): Result[int, string] =
|
||||
let x = ?works() - ?works()
|
||||
result.ok(x)
|
||||
|
@ -209,6 +212,7 @@ doAssert vErr.isErr
|
|||
doAssert vErr2.isErr
|
||||
|
||||
vOk.get()
|
||||
vOk.expect("should never fail")
|
||||
|
||||
doAssert vOk.map(proc (): int = 42).get() == 42
|
||||
|
||||
|
|
Loading…
Reference in New Issue