Actually, I'm tring to parse command line params by universal types.

Sample Code is below:
    
    
    import os
    import system
    import strutils
    import strformat
    import typeinfo
    import macros
    
    type
      CmdParam*[T] = object
        keyword: string
        parseProc: proc (p: string): T
        default: T
        defaultFlag: bool
        res: seq[T]
    
    macro getAnyType(x: typed): auto =
      parseStmt($x.getTypeInst.toStrLit)
    
    proc newCmdParam*(keyword: string, default: auto, parseProc: proc): auto =
      proc newCmdParamTypedesc[T](keyword: string, default: T, parseProc: proc 
(p: string): T): CmdParam[T] =
        result.keyword = keyword
        result.default = default
        result.parseProc = parseProc
        result.defaultFlag = false
      result = newCmdParamTypedesc[getAnyType(default)](keyword, default, 
parseProc)
    
    macro len(t: tuple): int =
      len(t)
    
    macro extractObjectElementInTuple(definedTpl: typed, objectElementName: 
static[string]): auto =
      var length = len(definedTpl.getTypeInst)
      var elemStrSeq: seq[string]
      for itr in 0..<length:
        elemStrSeq.add($definedTpl.toStrLit & "[" & $itr & "]." & 
objectElementName)
      var command = "(" & elemStrSeq.join(",") & ")"
      parseStmt(command)
    
    proc parseCmdLineParamsImpl(cmdParamSeq: seq[string], pre: string, sep: 
string, params: var tuple): auto =
      let length = len(params)
      var itr: int
      var fixedCmd: string
      for cmdParam in cmdParamSeq:
        # I feel doubt that
        # rewritable tuple members will be yeilded
        # in the following for-loop.
        for prm in params.fields:
          fixedCmd = pre & prm.keyword & sep
          if cmdParam.startsWith(fixedCmd):
            try:
              prm.res.add(prm.parseProc(cmdParam.replace(fixedCmd, "")))
            except:
              echo "convert error"
      for prm in params.fields:
        if len(prm.res) == 0:
          if prm.defaultFlag:
            prm.res = @[prm.default]
      result = extractObjectElementInTuple(params, "res")
    
    proc parseCmdLineParams*(cmdParamSeq: seq[string], pre="--", sep=":", 
cmdParamTuple: var tuple): auto =
      parseCmdLineParamsImpl(cmdParamSeq, pre, sep, cmdParamTuple)
    
    ## An example from here ##
    
    type
      MyType[T] = object
        value: T
    
    proc toMyType(p: string): MyType[string] =
      result.value = p
    
    proc passString(p: string): string =
      p
    
    if isMainModule:
      var commandLineParamsSample: seq[string] = "--arg1:999 --arg2:9.99 
--arg3:abc --arg4:test".split(" ")
      var settings = (newCmdParam("arg1", 0, parseInt),
                      newCmdParam("arg2", 0.0, parseFloat),
                      newCmdParam("arg3", "", passString),
                      newCmdParam("arg4", MyType[string](value:"default"), 
toMyType)
                      )
      var val = 
commandLineParamsSample.parseCmdLineParams(cmdParamTuple=settings)
      # show
      for x in val.fields:
        echo x
        # @[999]
        # @[9.99]
        # @["abc"]
        # @[(value: "test")]
    
    
    Run

In my expectation, the yielded value is a copy of the tuple member.

And even if rewrite the value, it will not affect the original tuple.

There is no written description in the document.

Reply via email to