2021-03-05 21:07:48 +01:00
|
|
|
import std/options
|
2021-03-18 09:50:06 +01:00
|
|
|
import std/macros
|
2021-05-06 17:12:52 +02:00
|
|
|
import ./binding
|
2021-03-11 16:17:26 +01:00
|
|
|
import ./chaining
|
2021-03-18 17:58:48 +01:00
|
|
|
import ./indexing
|
2021-03-11 16:17:26 +01:00
|
|
|
import ./operators
|
2021-04-16 12:27:17 +02:00
|
|
|
import ./without
|
2021-03-05 21:07:48 +01:00
|
|
|
|
2022-04-03 09:08:32 +07:00
|
|
|
include ./private/errorban
|
2021-03-05 21:07:48 +01:00
|
|
|
|
2021-04-19 15:52:07 +02:00
|
|
|
export options except get
|
2021-05-06 17:12:52 +02:00
|
|
|
export binding
|
2021-03-11 16:17:26 +01:00
|
|
|
export chaining
|
2021-03-18 17:58:48 +01:00
|
|
|
export indexing
|
2021-04-16 12:27:17 +02:00
|
|
|
export without
|
2021-03-05 21:07:48 +01:00
|
|
|
|
|
|
|
|
template `?`*(T: typed): type Option[T] =
|
2021-06-04 17:34:48 +02:00
|
|
|
## Use `?` to make a type optional. For example the type `?int` is short for
|
|
|
|
|
## `Option[int]`.
|
|
|
|
|
|
2021-03-05 21:07:48 +01:00
|
|
|
Option[T]
|
|
|
|
|
|
2021-04-19 15:52:07 +02:00
|
|
|
template `!`*[T](option: ?T): T =
|
2021-06-04 17:34:48 +02:00
|
|
|
## Returns the value of an Option when you're absolutely sure that it
|
|
|
|
|
## contains value. Using `!` on an Option without a value raises a Defect.
|
|
|
|
|
|
2021-04-19 15:52:07 +02:00
|
|
|
option.get
|
|
|
|
|
|
2021-04-17 19:50:02 +02:00
|
|
|
template `->?`*[T,U](option: ?T, expression: ?U): ?U =
|
|
|
|
|
if option.isSome:
|
|
|
|
|
expression
|
|
|
|
|
else:
|
|
|
|
|
U.none
|
|
|
|
|
|
2021-06-04 16:38:44 +02:00
|
|
|
template `->?`*[T,U](option: ?T, expression: U): ?U =
|
|
|
|
|
option ->? expression.some
|
2021-03-05 21:07:48 +01:00
|
|
|
|
2021-04-17 19:50:02 +02:00
|
|
|
template `->?`*[T,U,V](options: (?T, ?U), expression: ?V): ?V =
|
|
|
|
|
if options[0].isSome and options[1].isSome:
|
|
|
|
|
expression
|
|
|
|
|
else:
|
|
|
|
|
V.none
|
|
|
|
|
|
2021-06-04 16:38:44 +02:00
|
|
|
template `->?`*[T,U,V](options: (?T, ?U), expression: V): ?V =
|
|
|
|
|
options ->? expression.some
|
|
|
|
|
|
2022-09-28 10:06:39 +02:00
|
|
|
proc `|?`*[T](option: ?T, fallback: T): T =
|
2021-06-04 17:34:48 +02:00
|
|
|
## Use the `|?` operator to supply a fallback value when an Option does not
|
|
|
|
|
## hold a value.
|
|
|
|
|
|
2021-03-11 16:17:26 +01:00
|
|
|
if option.isSome:
|
|
|
|
|
option.unsafeGet()
|
|
|
|
|
else:
|
|
|
|
|
fallback
|
2021-03-07 08:56:35 +01:00
|
|
|
|
2021-05-04 16:17:09 +02:00
|
|
|
macro `.?`*[T](option: ?T, brackets: untyped{nkBracket}): untyped =
|
|
|
|
|
let index = brackets[0]
|
|
|
|
|
quote do:
|
2022-09-28 10:06:39 +02:00
|
|
|
block:
|
|
|
|
|
let evaluated = `option`
|
|
|
|
|
type U = typeof(evaluated.unsafeGet().?[`index`].unsafeGet())
|
|
|
|
|
if evaluated.isSome:
|
|
|
|
|
evaluated.unsafeGet().?[`index`]
|
|
|
|
|
else:
|
|
|
|
|
U.none
|
2021-05-04 16:17:09 +02:00
|
|
|
|
2021-03-08 16:11:01 +01:00
|
|
|
Option.liftUnary(`-`)
|
|
|
|
|
Option.liftUnary(`+`)
|
|
|
|
|
Option.liftUnary(`@`)
|
|
|
|
|
Option.liftBinary(`[]`)
|
|
|
|
|
Option.liftBinary(`*`)
|
|
|
|
|
Option.liftBinary(`/`)
|
|
|
|
|
Option.liftBinary(`div`)
|
|
|
|
|
Option.liftBinary(`mod`)
|
|
|
|
|
Option.liftBinary(`shl`)
|
|
|
|
|
Option.liftBinary(`shr`)
|
|
|
|
|
Option.liftBinary(`+`)
|
|
|
|
|
Option.liftBinary(`-`)
|
|
|
|
|
Option.liftBinary(`&`)
|
|
|
|
|
Option.liftBinary(`<=`)
|
|
|
|
|
Option.liftBinary(`<`)
|
|
|
|
|
Option.liftBinary(`>=`)
|
|
|
|
|
Option.liftBinary(`>`)
|