To break this down into multiple steps `varargs[T, conversionProc]` allows you 
to take in comma separated values or arrays, but since arrays have to be 
homogeneous you cannot do `query = {}` or `query = []`.
    
    
    proc toStrTup[T, Y](a: (T, Y)): (string, string) = ($a[0], $a[1])
    
    proc doThing(args: varargs[(string, string), toStrTup]) = echo args
    
    doThing (10, 20), ("hmm", 40), ("huh", (10, 20, 30))
    
    
    Run

If that suffices it's done and we can all go home.

If that does not suffice we need to bring in macros to solve this problem. 
Something along the lines of
    
    
    import std/[macros, strformat]
    
    macro toQuery*(arr: untyped, querySize: static range[2..int.high]): untyped 
=
      result = nnkBracket.newNimNode()
      case arr.kind
      of nnkBracket:
        for ele in arr:
          if ele.kind in {nnkTupleConstr, nnkPar}:
            if ele.len != querySize:
              error(fmt"Expected a tuple airty of '{querySize}', but got a size 
of '{ele.len}'", ele)
            result.add nnkTupleConstr.newNimNode()
            for field in ele:
              result[^1].add newCall("$", field)
      
      of nnkTableConstr:
        if querySize != 2:
          error(fmt"Expected a tuple of '{querySize}' airty, but got a table.", 
arr)
        for tupleConstr in arr:
          result.add nnkTupleConstr.newNimNode
          result[^1].add newCall("$", tupleConstr[0])
          result[^1].add newCall("$", tupleConstr[1])
      else:
        error(fmt"Expected '{{a: b}}' or '[(a, b)]', but got '{arr.repr}'.", 
arr)
      echo result.repr
    
    template toQuery*(arr: untyped): untyped = toQuery(arr, 2)
    
    
    proc doThing(args: varargs[(string, string)]) = echo args
    
    let a = @[10, 20, 30, 40]
    doThing toQuery {10: 20, "hmm": "huh", (10, 20, 30):  a}
    doThing toQuery [(10, 20), ("hmm", "huh"), ((10, 20, 30), a)]
    assert toQuery([(10, 20), ("hmm", "huh"), ((10, 20, 30), a)]) == 
toQuery({10: 20, "hmm": "huh", (10, 20, 30):  a})
    
    
    Run

Notice that due to how semantic analysis works you cannot do `{...}.toQuery` or 
`[...].toQuery`.

Reply via email to