84 lines
1.9 KiB
Nim
Raw Normal View History

import std/options
2021-03-18 09:50:06 +01:00
import std/macros
2021-05-06 17:12:52 +02:00
import ./binding
import ./chaining
2021-03-18 17:58:48 +01:00
import ./indexing
import ./operators
2021-04-16 12:27:17 +02:00
import ./without
include ./private/errorban
export options except get
2021-05-06 17:12:52 +02:00
export binding
export chaining
2021-03-18 17:58:48 +01:00
export indexing
2021-04-16 12:27:17 +02:00
export without
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]`.
Option[T]
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.
option.get
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
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
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.
if option.isSome:
option.unsafeGet()
else:
fallback
macro `.?`*[T](option: ?T, brackets: untyped{nkBracket}): untyped =
let index = brackets[0]
quote do:
block:
let evaluated = `option`
type U = typeof(evaluated.unsafeGet().?[`index`].unsafeGet())
if evaluated.isSome:
evaluated.unsafeGet().?[`index`]
else:
U.none
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(`>`)