results: add `mapConvertErr`, `mapCastErr` (#178)

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
https://github.com/status-im/nim-stew/pull/34, though this inherently,
and perhaps rightly, would be limited to "error-free" conversions.

Regardless, these helpers provide balance to the existing API.
This commit is contained in:
Jacek Sieka 2023-06-28 10:27:45 +02:00 committed by GitHub
parent 9958aac68a
commit d085e48e89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 0 deletions

View File

@ -628,6 +628,36 @@ func mapCast*[T0: not void, E](
else: else:
result.err(self.eResultPrivate) 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] = template `and`*[T0, E, T1](self: Result[T0, E], other: Result[T1, E]): Result[T1, E] =
## Evaluate `other` iff self.isOk, else return error ## Evaluate `other` iff self.isOk, else return error
## fail-fast - will not evaluate other if a is an error ## fail-fast - will not evaluate other if a is an error

View File

@ -131,6 +131,9 @@ block:
doAssert (rErr.orErr(32)).error == 32 doAssert (rErr.orErr(32)).error == 32
doAssert (rOk.orErr(failFast())).get() == rOk.get() doAssert (rOk.orErr(failFast())).get() == rOk.get()
doAssert rErr.mapConvertErr(cstring).error() == cstring(rErr.error())
doAssert rErr.mapCastErr(seq[byte]).error() == cast[seq[byte]](rErr.error())
# string conversion # string conversion
doAssert $rOk == "ok(42)" doAssert $rOk == "ok(42)"
doAssert $rErr == "err(dummy)" doAssert $rErr == "err(dummy)"