nim-cli-utils/cliutils/config.nim

65 lines
2.1 KiB
Nim
Raw Normal View History

2022-01-21 18:04:40 -06:00
import docopt, json, nre, os, strtabs, strutils
type
CombinedConfig* = object
docopt*: Table[string, Value]
json*: JsonNode
template walkFieldDefs*(t: NimNode, body: untyped) =
let tTypeImpl = t.getTypeImpl
var nodeToItr: NimNode
if tTypeImpl.typeKind == ntyObject: nodeToItr = tTypeImpl[2]
elif tTypeImpl.typeKind == ntyTypeDesc: nodeToItr = tTypeImpl.getType[1].getType[2]
else: error $t & " is not an object or type desc (it's a " & $tTypeImpl.typeKind & ")."
for fieldDef {.inject.} in nodeToItr.children:
# ignore AST nodes that are not field definitions
if fieldDef.kind == nnkIdentDefs:
let fieldIdent {.inject.} = fieldDef[0]
let fieldType {.inject.} = fieldDef[1]
body
elif fieldDef.kind == nnkSym:
let fieldIdent {.inject.} = fieldDef
let fieldType {.inject.} = fieldDef.getType
body
# TODO: Generic config loader
# macro loadConfig*(filePath: string, cfgType: typed, args: Table[string, docopt.Value): untyped =
# result = newNimNode(nnkObjConstr).(cfgType)
#
# var idx = 0
# cfgType.walkFieldDefs:
# let valLookup = quote do: `getVal`(
proc getVal*(cfg: CombinedConfig, key: string): string =
let argKey = "--" & key
let envKey = key.replace('-', '_').toUpper
let jsonKey = key.replace(re"(-\w)", proc (m: RegexMatch): string = ($m)[1..1].toUpper)
if cfg.docopt.contains(argKey) and cfg.docopt[argKey]: return $cfg.docopt[argKey]
elif existsEnv(envKey): return getEnv(envKey)
elif cfg.json.hasKey(jsonKey):
let node = cfg.json[jsonKey]
case node.kind
of JString: return node.getStr
of JInt: return $node.getInt
of JFloat: return $node.getFloat
of JBool: return $node.getBool
of JNull: return ""
of JObject: return $node
of JArray: return $node
else: raise newException(ValueError, "cannot find a configuration value for \"" & key & "\"")
proc getVal*(cfg: CombinedConfig, key, default: string): string =
try: return getVal(cfg, key)
except: return default
proc loadEnv*(): StringTableRef =
result = newStringTable()
for k, v in envPairs():
result[k] = v