rm TaintedString for string; some proc -> func (#53)

* rm TaintedString for string; some proc -> func

* procs which interact with macros in certain ways can't be funcs in Nim 1.2
This commit is contained in:
tersec 2022-06-03 18:24:59 +00:00 committed by GitHub
parent d06f6187dc
commit fc03a0c4e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 93 deletions

View File

@ -338,7 +338,7 @@ Furthermore, you can extend the behavior of the library by providing
overloads such as: overloads such as:
```nim ```nim
proc parseCmdArg*(T: type Foo, p: TaintedString): T = proc parseCmdArg*(T: type Foo, p: string): T =
## This provides parsing and validation for fields having the `Foo` type. ## This provides parsing and validation for fields having the `Foo` type.
## You should raise `ConfigurationError` in case of detected problems. ## You should raise `ConfigurationError` in case of detected problems.
... ...

View File

@ -60,7 +60,7 @@ const
confutils_description_width {.intdefine.} = 80 confutils_description_width {.intdefine.} = 80
confutils_narrow_terminal_width {.intdefine.} = 36 confutils_narrow_terminal_width {.intdefine.} = 36
proc getFieldName(caseField: NimNode): NimNode = func getFieldName(caseField: NimNode): NimNode =
result = caseField result = caseField
if result.kind == nnkIdentDefs: result = result[0] if result.kind == nnkIdentDefs: result = result[0]
if result.kind == nnkPragmaExpr: result = result[0] if result.kind == nnkPragmaExpr: result = result[0]
@ -390,7 +390,7 @@ func getNextArgIdx(cmd: CmdInfo, consumedArgIdx: int): int =
if cmd.opts[i].kind == Arg and cmd.opts[i].idx > consumedArgIdx: if cmd.opts[i].kind == Arg and cmd.opts[i].idx > consumedArgIdx:
return cmd.opts[i].idx return cmd.opts[i].idx
return -1 -1
proc noMoreArgsError(cmd: CmdInfo): string = proc noMoreArgsError(cmd: CmdInfo): string =
result = if cmd.isSubCommand: "The command '$1'" % [cmd.name] result = if cmd.isSubCommand: "The command '$1'" % [cmd.name]
@ -399,23 +399,23 @@ proc noMoreArgsError(cmd: CmdInfo): string =
if cmd.hasArgs: result.add " additional" if cmd.hasArgs: result.add " additional"
result.add " arguments" result.add " arguments"
proc findOpt(opts: openArray[OptInfo], name: string): OptInfo = func findOpt(opts: openArray[OptInfo], name: string): OptInfo =
for opt in opts: for opt in opts:
if cmpIgnoreStyle(opt.name, name) == 0 or if cmpIgnoreStyle(opt.name, name) == 0 or
cmpIgnoreStyle(opt.abbr, name) == 0: cmpIgnoreStyle(opt.abbr, name) == 0:
return opt return opt
proc findOpt(activeCmds: openArray[CmdInfo], name: string): OptInfo = func findOpt(activeCmds: openArray[CmdInfo], name: string): OptInfo =
for i in countdown(activeCmds.len - 1, 0): for i in countdown(activeCmds.len - 1, 0):
let found = findOpt(activeCmds[i].opts, name) let found = findOpt(activeCmds[i].opts, name)
if found != nil: return found if found != nil: return found
proc findCmd(cmds: openArray[CmdInfo], name: string): CmdInfo = func findCmd(cmds: openArray[CmdInfo], name: string): CmdInfo =
for cmd in cmds: for cmd in cmds:
if cmpIgnoreStyle(cmd.name, name) == 0: if cmpIgnoreStyle(cmd.name, name) == 0:
return cmd return cmd
proc findSubCmd(cmd: CmdInfo, name: string): CmdInfo = func findSubCmd(cmd: CmdInfo, name: string): CmdInfo =
let subCmdDiscriminator = cmd.getSubCmdDiscriminator let subCmdDiscriminator = cmd.getSubCmdDiscriminator
if subCmdDiscriminator != nil: if subCmdDiscriminator != nil:
let cmd = findCmd(subCmdDiscriminator.subCmds, name) let cmd = findCmd(subCmdDiscriminator.subCmds, name)
@ -423,7 +423,7 @@ proc findSubCmd(cmd: CmdInfo, name: string): CmdInfo =
return nil return nil
proc startsWithIgnoreStyle(s: string, prefix: string): bool = func startsWithIgnoreStyle(s: string, prefix: string): bool =
# Similar in spirit to cmpIgnoreStyle, but compare only the prefix. # Similar in spirit to cmpIgnoreStyle, but compare only the prefix.
var i = 0 var i = 0
var j = 0 var j = 0
@ -461,13 +461,13 @@ else:
template printCmdTree(cmd: CmdInfo) = discard template printCmdTree(cmd: CmdInfo) = discard
# TODO remove the overloads here to get better "missing overload" error message # TODO remove the overloads here to get better "missing overload" error message
proc parseCmdArg*(T: type InputDir, p: TaintedString): T = proc parseCmdArg*(T: type InputDir, p: string): T =
if not dirExists(p.string): if not dirExists(p.string):
raise newException(ValueError, "Directory doesn't exist") raise newException(ValueError, "Directory doesn't exist")
result = T(p) T(p)
proc parseCmdArg*(T: type InputFile, p: TaintedString): T = proc parseCmdArg*(T: type InputFile, p: string): T =
# TODO this is needed only because InputFile cannot be made # TODO this is needed only because InputFile cannot be made
# an alias of TypedInputFile at the moment, because of a generics # an alias of TypedInputFile at the moment, because of a generics
# caching issue # caching issue
@ -481,10 +481,10 @@ proc parseCmdArg*(T: type InputFile, p: TaintedString): T =
except IOError: except IOError:
raise newException(ValueError, "File not accessible") raise newException(ValueError, "File not accessible")
result = T(p.string) T(p.string)
proc parseCmdArg*(T: type TypedInputFile, p: TaintedString): T = proc parseCmdArg*(T: type TypedInputFile, p: string): T =
var path = p.string var path = p
when T.defaultExt.len > 0: when T.defaultExt.len > 0:
path = path.addFileExt(T.defaultExt) path = path.addFileExt(T.defaultExt)
@ -498,59 +498,59 @@ proc parseCmdArg*(T: type TypedInputFile, p: TaintedString): T =
except IOError: except IOError:
raise newException(ValueError, "File not accessible") raise newException(ValueError, "File not accessible")
result = T(path) T(path)
proc parseCmdArg*(T: type[OutDir|OutFile|OutPath], p: TaintedString): T = func parseCmdArg*(T: type[OutDir|OutFile|OutPath], p: string): T =
result = T(p) T(p)
proc parseCmdArg*[T](_: type Option[T], s: TaintedString): Option[T] = proc parseCmdArg*[T](_: type Option[T], s: string): Option[T] =
return some(parseCmdArg(T, s)) some(parseCmdArg(T, s))
template parseCmdArg*(T: type string, s: TaintedString): string = template parseCmdArg*(T: type string, s: string): string =
string s s
proc parseCmdArg*(T: type SomeSignedInt, s: TaintedString): T = func parseCmdArg*(T: type SomeSignedInt, s: string): T =
T parseBiggestInt(string s) T parseBiggestInt(string s)
proc parseCmdArg*(T: type SomeUnsignedInt, s: TaintedString): T = func parseCmdArg*(T: type SomeUnsignedInt, s: string): T =
T parseBiggestUInt(string s) T parseBiggestUInt(string s)
proc parseCmdArg*(T: type SomeFloat, p: TaintedString): T = func parseCmdArg*(T: type SomeFloat, p: string): T =
result = parseFloat(p) parseFloat(p)
proc parseCmdArg*(T: type bool, p: TaintedString): T = func parseCmdArg*(T: type bool, p: string): T =
try: try:
result = p.len == 0 or parseBool(p) p.len == 0 or parseBool(p)
except CatchableError: except CatchableError:
raise newException(ValueError, "'" & p.string & "' is not a valid boolean value. Supported values are on/off, yes/no, true/false or 1/0") raise newException(ValueError, "'" & p.string & "' is not a valid boolean value. Supported values are on/off, yes/no, true/false or 1/0")
proc parseCmdArg*(T: type enum, s: TaintedString): T = func parseCmdArg*(T: type enum, s: string): T =
parseEnum[T](string(s)) parseEnum[T](string(s))
proc parseCmdArgAux(T: type, s: TaintedString): T = # {.raises: [ValueError].} = proc parseCmdArgAux(T: type, s: string): T = # {.raises: [ValueError].} =
# The parseCmdArg procs are allowed to raise only `ValueError`. # The parseCmdArg procs are allowed to raise only `ValueError`.
# If you have provided your own specializations, please handle # If you have provided your own specializations, please handle
# all other exception types. # all other exception types.
mixin parseCmdArg mixin parseCmdArg
parseCmdArg(T, s) parseCmdArg(T, s)
proc completeCmdArg*(T: type enum, val: TaintedString): seq[string] = func completeCmdArg*(T: type enum, val: string): seq[string] =
for e in low(T)..high(T): for e in low(T)..high(T):
let as_str = $e let as_str = $e
if startsWithIgnoreStyle(as_str, val): if startsWithIgnoreStyle(as_str, val):
result.add($e) result.add($e)
proc completeCmdArg*(T: type SomeNumber, val: TaintedString): seq[string] = func completeCmdArg*(T: type SomeNumber, val: string): seq[string] =
return @[] @[]
proc completeCmdArg*(T: type bool, val: TaintedString): seq[string] = func completeCmdArg*(T: type bool, val: string): seq[string] =
return @[] @[]
proc completeCmdArg*(T: type string, val: TaintedString): seq[string] = func completeCmdArg*(T: type string, val: string): seq[string] =
return @[] @[]
proc completeCmdArg*(T: type[InputFile|TypedInputFile|InputDir|OutFile|OutDir|OutPath], proc completeCmdArg*(T: type[InputFile|TypedInputFile|InputDir|OutFile|OutDir|OutPath],
val: TaintedString): seq[string] = val: string): seq[string] =
when not defined(nimscript): when not defined(nimscript):
let (dir, name, ext) = splitFile(val) let (dir, name, ext) = splitFile(val)
let tail = name & ext let tail = name & ext
@ -581,36 +581,36 @@ proc completeCmdArg*(T: type[InputFile|TypedInputFile|InputDir|OutFile|OutDir|Ou
except OSError: except OSError:
discard discard
proc completeCmdArg*[T](_: type seq[T], val: TaintedString): seq[string] = func completeCmdArg*[T](_: type seq[T], val: string): seq[string] =
return @[] @[]
proc completeCmdArg*[T](_: type Option[T], val: TaintedString): seq[string] = proc completeCmdArg*[T](_: type Option[T], val: string): seq[string] =
mixin completeCmdArg mixin completeCmdArg
return completeCmdArg(type(T), val) return completeCmdArg(type(T), val)
proc completeCmdArgAux(T: type, val: TaintedString): seq[string] = proc completeCmdArgAux(T: type, val: string): seq[string] =
mixin completeCmdArg mixin completeCmdArg
return completeCmdArg(T, val) return completeCmdArg(T, val)
template setField[T](loc: var T, val: Option[TaintedString], defaultVal: untyped) = template setField[T](loc: var T, val: Option[string], defaultVal: untyped) =
type FieldType = type(loc) type FieldType = type(loc)
loc = if isSome(val): parseCmdArgAux(FieldType, val.get) loc = if isSome(val): parseCmdArgAux(FieldType, val.get)
else: FieldType(defaultVal) else: FieldType(defaultVal)
template setField[T](loc: var seq[T], val: Option[TaintedString], defaultVal: untyped) = template setField[T](loc: var seq[T], val: Option[string], defaultVal: untyped) =
if val.isSome: if val.isSome:
loc.add parseCmdArgAux(type(loc[0]), val.get) loc.add parseCmdArgAux(type(loc[0]), val.get)
else: else:
type FieldType = type(loc) type FieldType = type(loc)
loc = FieldType(defaultVal) loc = FieldType(defaultVal)
proc makeDefaultValue*(T: type): T = func makeDefaultValue*(T: type): T =
discard discard
proc requiresInput*(T: type): bool = func requiresInput*(T: type): bool =
not ((T is seq) or (T is Option) or (T is bool)) not ((T is seq) or (T is Option) or (T is bool))
proc acceptsMultipleValues*(T: type): bool = func acceptsMultipleValues*(T: type): bool =
T is seq T is seq
template debugMacroResult(macroName: string) {.dirty.} = template debugMacroResult(macroName: string) {.dirty.} =
@ -651,7 +651,7 @@ proc generateFieldSetters(RecordType: NimNode): NimNode =
newCall(bindSym"acceptsMultipleValues", fixedFieldType)) newCall(bindSym"acceptsMultipleValues", fixedFieldType))
result.add quote do: result.add quote do:
proc `completerName`(val: TaintedString): seq[string] {. proc `completerName`(val: string): seq[string] {.
nimcall nimcall
gcsafe gcsafe
sideEffect sideEffect
@ -659,7 +659,7 @@ proc generateFieldSetters(RecordType: NimNode): NimNode =
.} = .} =
return completeCmdArgAux(`fixedFieldType`, val) return completeCmdArgAux(`fixedFieldType`, val)
proc `setterName`(`configVar`: var `RecordType`, val: Option[TaintedString]) {. proc `setterName`(`configVar`: var `RecordType`, val: Option[string]) {.
nimcall nimcall
gcsafe gcsafe
sideEffect sideEffect
@ -678,14 +678,14 @@ proc generateFieldSetters(RecordType: NimNode): NimNode =
result.add settersArray result.add settersArray
debugMacroResult "Field Setters" debugMacroResult "Field Setters"
proc checkDuplicate(cmd: CmdInfo, opt: OptInfo, fieldName: NimNode) = func checkDuplicate(cmd: CmdInfo, opt: OptInfo, fieldName: NimNode) =
for x in cmd.opts: for x in cmd.opts:
if opt.name == x.name: if opt.name == x.name:
error "duplicate name detected: " & opt.name, fieldName error "duplicate name detected: " & opt.name, fieldName
if opt.abbr.len > 0 and opt.abbr == x.abbr: if opt.abbr.len > 0 and opt.abbr == x.abbr:
error "duplicate abbr detected: " & opt.abbr, fieldName error "duplicate abbr detected: " & opt.abbr, fieldName
proc validPath(path: var seq[CmdInfo], parent, node: CmdInfo): bool = func validPath(path: var seq[CmdInfo], parent, node: CmdInfo): bool =
for x in parent.opts: for x in parent.opts:
if x.kind != Discriminator: continue if x.kind != Discriminator: continue
for y in x.subCmds: for y in x.subCmds:
@ -697,7 +697,7 @@ proc validPath(path: var seq[CmdInfo], parent, node: CmdInfo): bool =
return true return true
false false
proc findPath(parent, node: CmdInfo): seq[CmdInfo] = func findPath(parent, node: CmdInfo): seq[CmdInfo] =
# find valid path from parent to node # find valid path from parent to node
result = newSeq[CmdInfo]() result = newSeq[CmdInfo]()
doAssert validPath(result, parent, node) doAssert validPath(result, parent, node)
@ -878,7 +878,7 @@ proc loadImpl[C, SecondarySources](
let confAddr = addr result let confAddr = addr result
template applySetter(setterIdx: int, cmdLineVal: TaintedString) = template applySetter(setterIdx: int, cmdLineVal: string) =
try: try:
fieldSetters[setterIdx][1](confAddr[], some(cmdLineVal)) fieldSetters[setterIdx][1](confAddr[], some(cmdLineVal))
inc fieldCounters[setterIdx] inc fieldCounters[setterIdx]
@ -889,7 +889,7 @@ proc loadImpl[C, SecondarySources](
getCurrentExceptionMsg()) getCurrentExceptionMsg())
when hasCompletions: when hasCompletions:
template getArgCompletions(opt: OptInfo, prefix: TaintedString): seq[string] = template getArgCompletions(opt: OptInfo, prefix: string): seq[string] =
fieldSetters[opt.idx][2](prefix) fieldSetters[opt.idx][2](prefix)
template required(opt: OptInfo): bool = template required(opt: OptInfo): bool =
@ -897,8 +897,8 @@ proc loadImpl[C, SecondarySources](
template activateCmd(discriminator: OptInfo, activatedCmd: CmdInfo) = template activateCmd(discriminator: OptInfo, activatedCmd: CmdInfo) =
let cmd = activatedCmd let cmd = activatedCmd
applySetter(discriminator.idx, if cmd.desc.len > 0: TaintedString(cmd.desc) applySetter(discriminator.idx, if cmd.desc.len > 0: cmd.desc
else: TaintedString(cmd.name)) else: cmd.name)
activeCmds.add cmd activeCmds.add cmd
nextArgIdx = cmd.getNextArgIdx(-1) nextArgIdx = cmd.getNextArgIdx(-1)
@ -1070,7 +1070,7 @@ proc loadImpl[C, SecondarySources](
# there is nothing left to do here. # there is nothing left to do here.
discard discard
elif opt.hasDefault: elif opt.hasDefault:
fieldSetters[opt.idx][1](conf, none[TaintedString]()) fieldSetters[opt.idx][1](conf, none[string]())
elif opt.required: elif opt.required:
fail "The required option '$1' was not specified" % [opt.name] fail "The required option '$1' was not specified" % [opt.name]
@ -1092,7 +1092,7 @@ template load*(
copyrightBanner, printUsage, quitOnFailure, copyrightBanner, printUsage, quitOnFailure,
secondarySourcesRef, secondarySources) secondarySourcesRef, secondarySources)
proc defaults*(Configuration: type): Configuration = func defaults*(Configuration: type): Configuration =
load(Configuration, cmdLine = @[], printUsage = false, quitOnFailure = false) load(Configuration, cmdLine = @[], printUsage = false, quitOnFailure = false)
proc dispatchImpl(cliProcSym, cliArgs, loadArgs: NimNode): NimNode = proc dispatchImpl(cliProcSym, cliArgs, loadArgs: NimNode): NimNode =
@ -1175,7 +1175,7 @@ macro cli*(args: varargs[untyped]): untyped =
debugMacroResult "CLI Code" debugMacroResult "CLI Code"
proc load*(f: TypedInputFile): f.ContentType = func load*(f: TypedInputFile): f.ContentType =
when f.Format is Unspecified or f.ContentType is Unspecified: when f.Format is Unspecified or f.ContentType is Unspecified:
{.fatal: "To use `InputFile.load`, please specify the Format and ContentType of the file".} {.fatal: "To use `InputFile.load`, please specify the Format and ContentType of the file".}

View File

@ -1,4 +1,4 @@
# Copyright 2018 Status Research & Development GmbH # Copyright 2018-2022 Status Research & Development GmbH
# Parts taken from Nim's Runtime Library (c) Copyright 2015 Andreas Rumpf # Parts taken from Nim's Runtime Library (c) Copyright 2015 Andreas Rumpf
type type
@ -17,11 +17,11 @@ type
cmds: seq[string] cmds: seq[string]
idx: int idx: int
kind*: CmdLineKind ## The detected command line token kind*: CmdLineKind ## The detected command line token
key*, val*: TaintedString ## Key and value pair; the key is the option key*, val*: string ## Key and value pair; the key is the option
## or the argument, and the value is not "" if ## or the argument, and the value is not "" if
## the option was given a value ## the option was given a value
proc parseWord(s: string, i: int, w: var string, func parseWord(s: string, i: int, w: var string,
delim: set[char] = {'\t', ' '}): int = delim: set[char] = {'\t', ' '}): int =
result = i result = i
if result < s.len and s[result] == '\"': if result < s.len and s[result] == '\"':
@ -37,7 +37,7 @@ proc parseWord(s: string, i: int, w: var string,
add(w, s[result]) add(w, s[result])
inc(result) inc(result)
proc initOptParser*(cmds: seq[string], shortNoVal: set[char]={}, func initOptParser*(cmds: seq[string], shortNoVal: set[char]={},
longNoVal: seq[string] = @[]; longNoVal: seq[string] = @[];
allowWhitespaceAfterColon = true): OptParser = allowWhitespaceAfterColon = true): OptParser =
result.pos = 0 result.pos = 0
@ -48,10 +48,10 @@ proc initOptParser*(cmds: seq[string], shortNoVal: set[char]={},
result.allowWhitespaceAfterColon = allowWhitespaceAfterColon result.allowWhitespaceAfterColon = allowWhitespaceAfterColon
result.cmds = cmds result.cmds = cmds
result.kind = cmdEnd result.kind = cmdEnd
result.key = TaintedString"" result.key = ""
result.val = TaintedString"" result.val = ""
proc handleShortOption(p: var OptParser; cmd: string) = func handleShortOption(p: var OptParser; cmd: string) =
var i = p.pos var i = p.pos
p.kind = cmdShortOption p.kind = cmdShortOption
if i < cmd.len: if i < cmd.len:
@ -67,7 +67,7 @@ proc handleShortOption(p: var OptParser; cmd: string) =
inc(i) inc(i)
p.inShortState = false p.inShortState = false
while i < cmd.len and cmd[i] in {'\t', ' '}: inc(i) while i < cmd.len and cmd[i] in {'\t', ' '}: inc(i)
p.val = TaintedString substr(cmd, i) p.val = substr(cmd, i)
p.pos = 0 p.pos = 0
inc p.idx inc p.idx
else: else:
@ -77,7 +77,7 @@ proc handleShortOption(p: var OptParser; cmd: string) =
p.pos = 0 p.pos = 0
inc p.idx inc p.idx
proc next*(p: var OptParser) = func next*(p: var OptParser) =
## Parses the next token. ## Parses the next token.
## ##
## ``p.kind`` describes what kind of token has been parsed. ``p.key`` and ## ``p.kind`` describes what kind of token has been parsed. ``p.key`` and
@ -119,12 +119,12 @@ proc next*(p: var OptParser) =
inc p.idx inc p.idx
i = 0 i = 0
if p.idx < p.cmds.len: if p.idx < p.cmds.len:
p.val = TaintedString p.cmds[p.idx].substr(i) p.val = p.cmds[p.idx].substr(i)
elif len(p.longNoVal) > 0 and p.key.string notin p.longNoVal and p.idx+1 < p.cmds.len: elif len(p.longNoVal) > 0 and p.key notin p.longNoVal and p.idx+1 < p.cmds.len:
p.val = TaintedString p.cmds[p.idx+1] p.val = p.cmds[p.idx+1]
inc p.idx inc p.idx
else: else:
p.val = TaintedString"" p.val = ""
inc p.idx inc p.idx
p.pos = 0 p.pos = 0
else: else:
@ -132,11 +132,11 @@ proc next*(p: var OptParser) =
handleShortOption(p, p.cmds[p.idx]) handleShortOption(p, p.cmds[p.idx])
else: else:
p.kind = cmdArgument p.kind = cmdArgument
p.key = TaintedString p.cmds[p.idx] p.key = p.cmds[p.idx]
inc p.idx inc p.idx
p.pos = 0 p.pos = 0
iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedString] = iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: string] =
p.pos = 0 p.pos = 0
p.idx = 0 p.idx = 0
while true: while true:
@ -146,7 +146,7 @@ iterator getopt*(p: var OptParser): tuple[kind: CmdLineKind, key, val: TaintedSt
iterator getopt*(cmds: seq[string], iterator getopt*(cmds: seq[string],
shortNoVal: set[char]={}, longNoVal: seq[string] = @[]): shortNoVal: set[char]={}, longNoVal: seq[string] = @[]):
tuple[kind: CmdLineKind, key, val: TaintedString] = tuple[kind: CmdLineKind, key, val: string] =
var p = initOptParser(cmds, shortNoVal=shortNoVal, longNoVal=longNoVal) var p = initOptParser(cmds, shortNoVal=shortNoVal, longNoVal=longNoVal)
while true: while true:
next(p) next(p)

View File

@ -1,5 +1,5 @@
import import
options std/options
type type
ConfigurationError* = object of CatchableError ConfigurationError* = object of CatchableError
@ -21,15 +21,15 @@ type
SubCommandArgs* = distinct string SubCommandArgs* = distinct string
Flag* = object Flag* = object
name*: TaintedString name*: string
FlagWithValue* = object FlagWithValue* = object
name*: TaintedString name*: string
value*: TaintedString value*: string
FlagWithOptionalValue* = object FlagWithOptionalValue* = object
name*: TaintedString name*: string
value*: Option[TaintedString] value*: Option[string]
Unspecified* = object Unspecified* = object
Txt* = object Txt* = object
@ -61,4 +61,3 @@ template implicitlySelectable* {.pragma.}
## to allow the value of the discriminator to be determined ## to allow the value of the discriminator to be determined
## implicitly when the user specifies any of the sub-options ## implicitly when the user specifies any of the sub-options
## that depend on the disciminator value. ## that depend on the disciminator value.

View File

@ -4,14 +4,14 @@ export stewNet
export ValidIpAddress export ValidIpAddress
func parseCmdArg*(T: type ValidIpAddress, s: TaintedString): T = func parseCmdArg*(T: type ValidIpAddress, s: string): T =
ValidIpAddress.init(string s) ValidIpAddress.init(string s)
proc completeCmdArg*(T: type ValidIpAddress, val: TaintedString): seq[string] = func completeCmdArg*(T: type ValidIpAddress, val: string): seq[string] =
# TODO: Maybe complete the local IP address? # TODO: Maybe complete the local IP address?
return @[] @[]
func parseCmdArg*(T: type Port, s: TaintedString): T = func parseCmdArg*(T: type Port, s: string): T =
template fail = template fail =
raise newException(ValueError, raise newException(ValueError,
"The supplied port must be an integer value in the range 1-65535") "The supplied port must be an integer value in the range 1-65535")
@ -25,6 +25,5 @@ func parseCmdArg*(T: type Port, s: TaintedString): T =
return Port(intVal) return Port(intVal)
proc completeCmdArg*(T: type Port, val: TaintedString): seq[string] = func completeCmdArg*(T: type Port, val: string): seq[string] =
return @[] @[]

View File

@ -120,11 +120,11 @@ type
func defaultDataDir(conf: TestConf): string = func defaultDataDir(conf: TestConf): string =
discard discard
func parseCmdArg*(T: type GraffitiBytes, input: TaintedString): T func parseCmdArg*(T: type GraffitiBytes, input: string): T
{.raises: [ValueError, Defect].} = {.raises: [ValueError, Defect].} =
discard discard
func completeCmdArg*(T: type GraffitiBytes, input: TaintedString): seq[string] = func completeCmdArg*(T: type GraffitiBytes, input: string): seq[string] =
@[] @[]
func defaultAdminListenAddress*(conf: TestConf): ValidIpAddress = func defaultAdminListenAddress*(conf: TestConf): ValidIpAddress =

View File

@ -13,11 +13,11 @@ type
desc: "La2" desc: "La2"
name: "la2" }: specialint.SInt name: "la2" }: specialint.SInt
proc parseCmdArg(T: type specialint.SInt, p: TaintedString): T = func parseCmdArg(T: type specialint.SInt, p: string): T =
parseInt(string p).T parseInt(string p).T
proc completeCmdArg(T: type specialint.SInt, val: TaintedString): seq[string] = func completeCmdArg(T: type specialint.SInt, val: string): seq[string] =
return @[] @[]
suite "Qualified Ident": suite "Qualified Ident":
test "Qualified Ident": test "Qualified Ident":