Add documentation comments
This commit is contained in:
parent
a2ded4f01a
commit
4a1783c472
|
@ -63,7 +63,7 @@ else:
|
|||
# this is reached, and y is not defined
|
||||
```
|
||||
|
||||
The `without` statement can be used to place guards that ensure that an optional
|
||||
The `without` statement can be used to place guards that ensure that an Option
|
||||
contains a value:
|
||||
|
||||
```nim
|
||||
|
|
|
@ -18,6 +18,10 @@ template bindVar(name, expression): bool =
|
|||
option.isSome
|
||||
|
||||
macro `=?`*(name, expression): bool =
|
||||
## The `=?` operator lets you bind the value inside an Option or Result to a
|
||||
## new variable. It can be used inside of a conditional expression, for
|
||||
## instance in an `if` statement.
|
||||
|
||||
name.expectKind({nnkIdent, nnkVarTy})
|
||||
if name.kind == nnkIdent:
|
||||
quote do: bindLet(`name`, `expression`)
|
||||
|
|
|
@ -8,30 +8,50 @@ func expectSym(node: NimNode) =
|
|||
node.expectKind({nnkSym, nnkOpenSymChoice, nnkClosedSymChoice})
|
||||
|
||||
template `.?`*(option: typed, identifier: untyped{nkIdent}): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
# chain is of shape: option.?identifier
|
||||
when not compiles(typeof(option.unsafeGet.identifier)):
|
||||
{.error: ".? chain cannot return void".}
|
||||
option ->? option.unsafeGet.identifier
|
||||
|
||||
macro `.?`*(option: typed, infix: untyped{nkInfix}): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
# chain is of shape: option.?left `operator` right
|
||||
let left = infix[1]
|
||||
infix[1] = quote do: `option`.?`left`
|
||||
infix
|
||||
|
||||
macro `.?`*(option: typed, bracket: untyped{nkBracketExpr}): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
# chain is of shape: option.?left[right]
|
||||
let left = bracket[0]
|
||||
bracket[0] = quote do: `option`.?`left`
|
||||
bracket
|
||||
|
||||
macro `.?`*(option: typed, dot: untyped{nkDotExpr}): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
# chain is of shape: option.?left.right
|
||||
let left = dot[0]
|
||||
dot[0] = quote do: `option`.?`left`
|
||||
dot
|
||||
|
||||
macro `.?`*(option: typed, call: untyped{nkCall}): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
let procedure = call[0]
|
||||
if call.len == 1:
|
||||
# chain is of shape: option.?procedure()
|
||||
|
@ -53,6 +73,10 @@ macro `.?`*(option: typed, call: untyped{nkCall}): untyped =
|
|||
quote do: `option` ->? `call`
|
||||
|
||||
macro `.?`*(option: typed, symbol: untyped): untyped =
|
||||
## The `.?` chaining operator is used to safely access fields and call procs
|
||||
## on Options or Results. The expression is only evaluated when the preceding
|
||||
## Option or Result has a value.
|
||||
|
||||
symbol.expectSym()
|
||||
let expression = ident($symbol)
|
||||
quote do: `option`.?`expression`
|
||||
|
|
|
@ -15,9 +15,15 @@ export indexing
|
|||
export without
|
||||
|
||||
template `?`*(T: typed): type Option[T] =
|
||||
## Use `?` to make a type optional. For example the type `?int` is short for
|
||||
## `Option[int]`.
|
||||
|
||||
Option[T]
|
||||
|
||||
template `!`*[T](option: ?T): T =
|
||||
## 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 =
|
||||
|
@ -39,6 +45,9 @@ template `->?`*[T,U,V](options: (?T, ?U), expression: V): ?V =
|
|||
options ->? expression.some
|
||||
|
||||
template `|?`*[T](option: ?T, fallback: T): T =
|
||||
## Use the `|?` operator to supply a fallback value when an Option does not
|
||||
## hold a value.
|
||||
|
||||
if option.isSome:
|
||||
option.unsafeGet()
|
||||
else:
|
||||
|
|
|
@ -18,33 +18,57 @@ export without
|
|||
type ResultFailure* = object of CatchableError
|
||||
|
||||
template `?!`*(T: typed): type Result[T, ref CatchableError] =
|
||||
## Use `?!` make a Result type. These Result types either hold a value or
|
||||
## an error. For example the type `?!int` is short for
|
||||
## `Result[int, ref CatchableError]`.
|
||||
|
||||
Result[T, ref CatchableError]
|
||||
|
||||
template `!`*[T](value: ?!T): T =
|
||||
## Returns the value of a Result when you're absolutely sure that it
|
||||
## contains value. Using `!` on a Result without a value raises a Defect.
|
||||
|
||||
value.get
|
||||
|
||||
proc success*[T](value: T): ?!T =
|
||||
## Creates a successfull Result containing the value.
|
||||
##
|
||||
ok(?!T, value)
|
||||
|
||||
proc success*: ?!void =
|
||||
## Creates a successfull Result without a value.
|
||||
|
||||
ok(?!void)
|
||||
|
||||
proc failure*(T: type, error: ref CatchableError): ?!T =
|
||||
## Creates a failed Result containing the error.
|
||||
|
||||
err(?!T, error)
|
||||
|
||||
proc failure*(T: type, message: string): ?!T =
|
||||
## Creates a failed Result containing a `ResultFailure` with the specified
|
||||
## error message.
|
||||
|
||||
T.failure newException(ResultFailure, message)
|
||||
|
||||
template failure*(error: ref CatchableError): auto =
|
||||
## Creates a failed Result containing the error.
|
||||
|
||||
err error
|
||||
|
||||
template failure*(message: string): auto =
|
||||
## Creates a failed Result containing the error.
|
||||
|
||||
failure newException(ResultFailure, message)
|
||||
|
||||
proc isSuccess*[T](value: ?!T): bool =
|
||||
## Returns true when the Result contains a value.
|
||||
|
||||
value.isOk
|
||||
|
||||
proc isFailure*[T](value: ?!T): bool =
|
||||
## Returns true when the Result contains an error.
|
||||
|
||||
value.isErr
|
||||
|
||||
template `->?`*[T,U](value: ?!T, expression: ?!U): ?!U =
|
||||
|
@ -68,9 +92,14 @@ template `->?`*[T,U,V](values: (?!T, ?!U), expression: V): ?!V =
|
|||
values ->? expression.success
|
||||
|
||||
template `|?`*[T,E](value: Result[T,E], fallback: T): T =
|
||||
## Use the `|?` operator to supply a fallback value when a Result does not
|
||||
## hold a value.
|
||||
|
||||
value.valueOr(fallback)
|
||||
|
||||
proc option*[T,E](value: Result[T,E]): ?T =
|
||||
## Converts a Result into an Option.
|
||||
|
||||
if value.isOk:
|
||||
try: # workaround for erroneouos exception tracking when T is a closure
|
||||
value.unsafeGet.some
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
template without*(expression, body) =
|
||||
## Used to place guards that ensure that an Option or Result contains a value.
|
||||
|
||||
let ok = expression
|
||||
if not ok:
|
||||
body
|
||||
|
|
Loading…
Reference in New Issue