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!
|
## Note: If error is of exception type, it will be raised instead!
|
||||||
error*: E
|
error*: E
|
||||||
|
|
||||||
|
ResultDefect* = object of Defect
|
||||||
|
|
||||||
Result*[T, E] = object
|
Result*[T, E] = object
|
||||||
## Result type that can hold either a value or an error, but not both
|
## 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](
|
func mapConvert*[T0, E0](
|
||||||
self: Result[T0, E0], T1: type): Result[T1, E0] {.inline.} =
|
self: Result[T0, E0], T1: type): Result[T1, E0] {.inline.} =
|
||||||
## Convert result value to A using an implicit conversion
|
## Convert result value to A using an conversion
|
||||||
## Would be nice if it was automatic...
|
# Would be nice if it was automatic...
|
||||||
if self.isOk: result.ok(self.v)
|
if self.isOk: result.ok(T1(self.v))
|
||||||
else: result.err(self.e)
|
else: result.err(self.e)
|
||||||
|
|
||||||
func mapCast*[T0, E0](
|
func mapCast*[T0, E0](
|
||||||
|
@ -342,6 +344,25 @@ template unsafeGet*[T, E](self: Result[T, E]): T =
|
||||||
|
|
||||||
self.v
|
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 =
|
func `$`*(self: Result): string =
|
||||||
## Returns string representation of `self`
|
## Returns string representation of `self`
|
||||||
if self.isOk: "Ok(" & $self.v & ")"
|
if self.isOk: "Ok(" & $self.v & ")"
|
||||||
|
@ -416,6 +437,10 @@ template unsafeGet*[E](self: Result[void, E]) =
|
||||||
## See also: Option.unsafeGet
|
## See also: Option.unsafeGet
|
||||||
assert not self.isErr
|
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 =
|
func `$`*[E](self: Result[void, E]): string =
|
||||||
## Returns string representation of `self`
|
## Returns string representation of `self`
|
||||||
if self.isOk: "Ok()"
|
if self.isOk: "Ok()"
|
||||||
|
|
|
@ -107,6 +107,7 @@ doAssert $rOk == "Ok(42)"
|
||||||
|
|
||||||
doAssert rOk.mapConvert(int64)[] == int64(42)
|
doAssert rOk.mapConvert(int64)[] == int64(42)
|
||||||
doAssert rOk.mapCast(int8)[] == int8(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
|
# TODO there's a bunch of operators that one could lift through magic - this
|
||||||
# is mainly an example
|
# is mainly an example
|
||||||
|
@ -147,6 +148,8 @@ func testErr(): Result[int, string] =
|
||||||
doAssert testOk()[] == 42
|
doAssert testOk()[] == 42
|
||||||
doAssert testErr().error == "323"
|
doAssert testErr().error == "323"
|
||||||
|
|
||||||
|
doAssert testOk().expect("testOk never fails") == 42
|
||||||
|
|
||||||
func testQn(): Result[int, string] =
|
func testQn(): Result[int, string] =
|
||||||
let x = ?works() - ?works()
|
let x = ?works() - ?works()
|
||||||
result.ok(x)
|
result.ok(x)
|
||||||
|
@ -209,6 +212,7 @@ doAssert vErr.isErr
|
||||||
doAssert vErr2.isErr
|
doAssert vErr2.isErr
|
||||||
|
|
||||||
vOk.get()
|
vOk.get()
|
||||||
|
vOk.expect("should never fail")
|
||||||
|
|
||||||
doAssert vOk.map(proc (): int = 42).get() == 42
|
doAssert vOk.map(proc (): int = 42).get() == 42
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue