Created
October 1, 2018 21:28
-
-
Save copygirl/fd886e0a739b66a93aee312b411abc0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import | |
future, | |
macros, | |
options | |
export UnpackError | |
type | |
Result*[T,Err] = object | |
## A type which stores the result value of a procedure, or error if one occurred. | |
case suc: bool | |
of true: val: T | |
of false: err: Err | |
proc isSuccess*[T,Err](res: Result[T,Err]): bool = | |
res.suc | |
proc isFail*[T,Err](res: Result[T,Err]): bool = not | |
res.suc | |
proc getValue*[T,Err](res: Result[T,Err]): T = | |
## Returns the success value of the Result. If it failed, `UnpackError` is raised. | |
if res.isFail: raise newException(UnpackError, "Can't obtain value from a failed `Result`") | |
res.val | |
proc getError*[T,Err](res: Result[T,Err]): Err = | |
## Returns the error of the Result. If it succeeded, `UnpackError` is raised. | |
if res.isSuccess: raise newException(UnpackError, "Can't obtain error from a successful `Result`") | |
res.err | |
template success*[T](value: T, Err: typedesc): Result[T,Err] = | |
## Creates a `Result` that contains a successful result `value`. | |
Result[T,Err](suc: true, val: value) | |
template error*[Err](err: Err, T: typedesc): Result[T,Err] = | |
## Creates a `Result` that contains the error `err`. | |
Result[T,Err](suc: false, err: err) | |
proc errorIfNil*[T,Err](value: T, err: Err): Result[T,Err] = | |
## Returns a `Result` that contains `value` if it's not nil, otherwise `err`. | |
if not value.isNil: Result[T,Err](suc: true, val: value) #value.success(Err) | |
else: Result[T,Err](suc: false, err: err) #err.error(T) | |
proc errorIfNil*[T,Err](value: T, errFunc: () -> Err): Result[T,Err] = | |
## Returns a `Result` that contains `value` if it's | |
## not nil, otherwise an error created from `errFunc`. | |
if not value.isNil: value.success(Err) | |
else: errFunc().error(T) | |
proc option*[T,Err](res: Result[T, Err]): Option[T] = | |
## Transforms the `Result` into an `Option`, dropping potential error information. | |
if res.isSuccess: res.val.some | |
else: T.none | |
proc result*[T,Err](opt: Option[T], err: Err): Result[T,Err] = | |
## Transforms the `Option` into a `Result`, using `err` as its error if `none`. | |
if opt.isSome: opt.get().success(Err) | |
else: err.error(T) | |
proc result*[T,Err](opt: Option[T], errFunc: () -> Err): Result[T,Err] = | |
## Transforms the `Option` into a `Result`, using `errFunc` as its error if `none`. | |
if opt.isSome: opt.get().success(Err) | |
else: errFunc().error(T) | |
proc orValue*[T,Err](res: Result[T,Err], default: T): T = | |
## Returns the success value of the Result, or `default` if it failed. | |
if res.isSuccess: res.val | |
else: default | |
proc orValue*[T,Err](res: Result[T,Err], defaultFunc: Err -> T): T = | |
## Returns the success value of the Result, or the result of `defaultFunc` if it failed. | |
if res.isSuccess: res.val | |
else: defaultFunc(res.err) | |
proc orRaise*[T,Err:Exception](res: Result[T,Err]): T = | |
## Returns the success value of the Result, or raise the error if it failed. | |
if res.isFail: raise res.err | |
res.val | |
proc orRaise*[T,Err,Excp:Exception](res: Result[T,Err], errFunc: Err -> Excp): T = | |
## Returns the success value of the Result, or raise an error created by `errFunc`. | |
if res.isFail: raise errFunc(res.err) | |
res.val | |
proc map*[T,Err](res: Result[T,Err], callback: T -> void) = | |
## Runs `callback` if the Result succeeded. | |
if res.isSuccess: callback(res.val) | |
proc map*[T,R,Err](res: Result[T,Err], mapFunc: T -> R): Result[R,Err] = | |
## Returns a `Result` with `mapFunc` applied to its success | |
## value if it succeeded, or passing through its error. | |
if res.isSuccess: mapFunc(res.val).success(Err) | |
else: res.err.error(T) | |
proc map*[T,R,Err](res: Result[T,Err], mapFunc: T -> Result[R,Err]): Result[R,Err] = | |
## Returns a `Result` with `mapFunc` applied to its success | |
## value if it succeeded, or passing through its error. | |
if res.isSuccess: mapFunc(res.val) | |
else: res.err.error(T) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment