Skip to content

Commit

Permalink
results: add mapConvertErr, mapCastErr
Browse files Browse the repository at this point in the history
We already have `mapConvert` and `mapCast` - this completes the API with
corresponding `Err` versions similar to `mapErr`.

The `Convert` / `Cast` operators are of somewhat dubious value - ie
they exist as "efficiency" shortcuts for `map` for the case that the
mapping should be done as a simple cast / conversion - an alternative
would be to deprecate these features and aim for some other, more
generic version that involves a type conversion library such as
#34, though this inherently,
and perhaps rightly, would be limited to "error-free" conversions.

Regardless, these helpers provide balance to the existing API.
  • Loading branch information
arnetheduck committed Apr 13, 2023
1 parent 763d54c commit 3a437e4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
30 changes: 30 additions & 0 deletions stew/results.nim
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,36 @@ func mapCast*[T0, E](
else:
result.err(self.eResultPrivate)

func mapConvertErr*[T, E0](
self: Result[T, E0], E1: type): Result[T, E1] {.inline.} =
## Convert result error to E1 using an conversion
# Would be nice if it was automatic...
when E0 is E1:
result = self
else:
if self.oResultPrivate:
when T is void:
result.ok()
else:
result.ok(self.vResultPrivate)
else:
when E1 is void:
result.err()
else:
result.err(E1(self.eResultPrivate))

func mapCastErr*[T, E0](
self: Result[T, E0], E1: type): Result[T, E1] {.inline.} =
## Convert result value to A using a cast
## Would be nice with nicer syntax...
if self.oResultPrivate:
when T is void:
result.ok()
else:
result.ok(self.vResultPrivate)
else:
result.err(cast[E1](self.eResultPrivate))

template `and`*[T0, E, T1](self: Result[T0, E], other: Result[T1, E]): Result[T1, E] =
## Evaluate `other` iff self.isOk, else return error
## fail-fast - will not evaluate other if a is an error
Expand Down
3 changes: 3 additions & 0 deletions tests/test_results.nim
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ block:
doAssert (rErr.orErr(32)).error == 32
doAssert (rOk.orErr(failFast())).get() == rOk.get()

doAssert rErr.mapConvertErr(cstring).error() == cstring(rErr.error())
doAssert rErr.mapCastErr(cstring).error() == cast[cstring](rErr.error())

# string conversion
doAssert $rOk == "ok(42)"
doAssert $rErr == "err(dummy)"
Expand Down

0 comments on commit 3a437e4

Please sign in to comment.