2021-03-18 09:50:06 +01:00
|
|
|
import std/macros
|
2021-03-05 21:07:48 +01:00
|
|
|
import ./resultsbase
|
2021-03-11 16:17:26 +01:00
|
|
|
import ./options
|
|
|
|
|
import ./operators
|
2021-03-05 21:07:48 +01:00
|
|
|
|
|
|
|
|
include ./errorban
|
|
|
|
|
|
2021-04-15 09:39:37 +02:00
|
|
|
export resultsbase except ok, err, isOk, isErr
|
2021-03-05 21:07:48 +01:00
|
|
|
|
2021-03-16 09:45:06 +01:00
|
|
|
type ResultFailure* = object of CatchableError
|
|
|
|
|
|
2021-03-05 21:07:48 +01:00
|
|
|
template `?!`*(T: typed): type Result[T, ref CatchableError] =
|
|
|
|
|
Result[T, ref CatchableError]
|
|
|
|
|
|
2021-03-11 16:17:26 +01:00
|
|
|
proc success*[T](value: T): ?!T =
|
2021-03-05 21:07:48 +01:00
|
|
|
ok(?!T, value)
|
|
|
|
|
|
2021-03-11 16:17:26 +01:00
|
|
|
proc failure*(T: type, error: ref CatchableError): ?!T =
|
2021-03-05 21:07:48 +01:00
|
|
|
err(?!T, error)
|
|
|
|
|
|
2021-03-16 09:45:06 +01:00
|
|
|
proc failure*(T: type, message: string): ?!T =
|
|
|
|
|
T.failure newException(ResultFailure, message)
|
|
|
|
|
|
2021-04-15 09:41:32 +02:00
|
|
|
template failure*(error: ref CatchableError): auto =
|
|
|
|
|
err error
|
|
|
|
|
|
|
|
|
|
template failure*(message: string): auto =
|
|
|
|
|
failure newException(ResultFailure, message)
|
|
|
|
|
|
2021-04-15 09:39:37 +02:00
|
|
|
proc isSuccess*[T](value: ?!T): bool =
|
|
|
|
|
value.isOk
|
|
|
|
|
|
|
|
|
|
proc isFailure*[T](value: ?!T): bool =
|
|
|
|
|
value.isErr
|
|
|
|
|
|
2021-03-13 11:46:26 +01:00
|
|
|
template `->?`*[T,U](value: ?!T, expression: U): ?!U =
|
2021-04-15 09:39:37 +02:00
|
|
|
if value.isFailure:
|
2021-03-13 11:46:26 +01:00
|
|
|
U.failure(value.error)
|
2021-03-05 21:07:48 +01:00
|
|
|
else:
|
2021-03-11 16:17:26 +01:00
|
|
|
expression.success
|
|
|
|
|
|
2021-03-13 11:46:26 +01:00
|
|
|
template `->?`*[T,U,V](values: (?!T, ?!U), expression: V): ?!V =
|
2021-04-15 09:39:37 +02:00
|
|
|
if values[0].isFailure:
|
2021-03-13 11:46:26 +01:00
|
|
|
V.failure(values[0].error)
|
2021-04-15 09:39:37 +02:00
|
|
|
elif values[1].isFailure:
|
2021-03-13 11:46:26 +01:00
|
|
|
V.failure(values[1].error)
|
2021-03-11 16:17:26 +01:00
|
|
|
else:
|
|
|
|
|
expression.success
|
2021-03-05 21:07:48 +01:00
|
|
|
|
|
|
|
|
template `|?`*[T](value: ?!T, fallback: T): T =
|
|
|
|
|
value.valueOr(fallback)
|
|
|
|
|
|
2021-03-18 16:59:55 +01:00
|
|
|
template `=?`*[T](name: untyped{nkIdent}, expression: ?!T): bool =
|
|
|
|
|
let value = expression
|
2021-03-05 21:07:48 +01:00
|
|
|
template name: T {.used.} = value.unsafeGet()
|
2021-04-15 09:39:37 +02:00
|
|
|
value.isSuccess
|
2021-03-07 08:56:35 +01:00
|
|
|
|
2021-03-18 16:59:55 +01:00
|
|
|
macro `=?`*[T](variable: untyped{nkVarTy}, expression: ?!T): bool =
|
2021-03-18 09:50:06 +01:00
|
|
|
let name = variable[0]
|
|
|
|
|
quote do:
|
2021-03-18 16:59:55 +01:00
|
|
|
let value = `expression`
|
|
|
|
|
var `name` : typeof(value.unsafeGet())
|
2021-04-15 09:39:37 +02:00
|
|
|
if value.isSuccess:
|
2021-03-18 16:59:55 +01:00
|
|
|
`name` = value.unsafeGet()
|
2021-04-15 09:39:37 +02:00
|
|
|
value.isSuccess
|
2021-03-18 09:50:06 +01:00
|
|
|
|
2021-03-13 11:10:05 +01:00
|
|
|
proc option*[T,E](value: Result[T,E]): ?T =
|
2021-04-15 09:39:37 +02:00
|
|
|
if value.isSuccess:
|
2021-03-08 17:48:07 +01:00
|
|
|
value.unsafeGet.some
|
|
|
|
|
else:
|
|
|
|
|
T.none
|
|
|
|
|
|
2021-03-08 16:11:01 +01:00
|
|
|
Result.liftUnary(`-`)
|
|
|
|
|
Result.liftUnary(`+`)
|
|
|
|
|
Result.liftUnary(`@`)
|
|
|
|
|
Result.liftBinary(`[]`)
|
|
|
|
|
Result.liftBinary(`*`)
|
|
|
|
|
Result.liftBinary(`/`)
|
|
|
|
|
Result.liftBinary(`div`)
|
|
|
|
|
Result.liftBinary(`mod`)
|
|
|
|
|
Result.liftBinary(`shl`)
|
|
|
|
|
Result.liftBinary(`shr`)
|
|
|
|
|
Result.liftBinary(`+`)
|
|
|
|
|
Result.liftBinary(`-`)
|
|
|
|
|
Result.liftBinary(`&`)
|
|
|
|
|
Result.liftBinary(`<=`)
|
|
|
|
|
Result.liftBinary(`<`)
|
|
|
|
|
Result.liftBinary(`>=`)
|
|
|
|
|
Result.liftBinary(`>`)
|