diff --git a/questionable/chaining.nim b/questionable/chaining.nim index d14fcee..a4f026b 100644 --- a/questionable/chaining.nim +++ b/questionable/chaining.nim @@ -1,33 +1,39 @@ import std/macros template `?.`*(option: typed, identifier: untyped{nkIdent}): untyped = + # chain is of shape: option?.identifier option ->? option.unsafeGet.identifier macro `?.`*(option: typed, infix: untyped{nkInfix}): untyped = + # 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 = + # 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 = + # 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 = let procedure = call[0] - if call.len > 1: - if procedure.kind == nnkDotExpr: - let (inner, outer) = (procedure[0], procedure[1]) - call[0] = outer - call.insert(1, quote do: `option`?.`inner`) - call - else: - call.insert(1, quote do: `option`.unsafeGet) - quote do: `option` ->? `call` + if call.len == 1: + # chain is of shape: option?.procedure() + quote do: `option`?.`procedure` + elif procedure.kind == nnkDotExpr: + # chain is of shape: option?.left.right(arguments) + let (left, right) = (procedure[0], procedure[1]) + call[0] = right + call.insert(1, quote do: `option`?.`left`) + call else: - quote do: `option`?.`procedure` + # chain is of shape: option?.procedure(arguments) + call.insert(1, quote do: `option`.unsafeGet) + quote do: `option` ->? `call`