result: add `expect` helper (#23)

* result: add `expect` helper

* result: use explicit conversion in mapConvert
This commit is contained in:
Jacek Sieka 2020-04-01 14:16:20 +02:00 committed by GitHub
parent d622c07a08
commit 7287fffebe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 3 deletions

View File

@ -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()"

View File

@ -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