mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-03-10 02:53:14 +00:00
* logosdelivery_get_available_configs collects and format WakuNodeConf options * simplify debug config output
144 lines
4.5 KiB
Nim
144 lines
4.5 KiB
Nim
import std/[macros]
|
|
|
|
type ConfigOptionMeta* = object
|
|
fieldName*: string
|
|
typeName*: string
|
|
cliName*: string
|
|
desc*: string
|
|
defaultValue*: string
|
|
command*: string
|
|
|
|
proc getPragmaValue(pragmaNode: NimNode, pragmaName: string): string {.compileTime.} =
|
|
if pragmaNode.kind != nnkPragma:
|
|
return ""
|
|
|
|
for item in pragmaNode:
|
|
if item.kind == nnkExprColonExpr and item[0].eqIdent(pragmaName):
|
|
return item[1].repr
|
|
|
|
return ""
|
|
|
|
proc getFieldName(fieldNode: NimNode): string {.compileTime.} =
|
|
case fieldNode.kind
|
|
of nnkPragmaExpr:
|
|
if fieldNode.len >= 1:
|
|
return getFieldName(fieldNode[0])
|
|
of nnkPostfix:
|
|
if fieldNode.len >= 2:
|
|
return getFieldName(fieldNode[1])
|
|
of nnkIdent, nnkSym:
|
|
return fieldNode.strVal
|
|
else:
|
|
discard
|
|
|
|
return fieldNode.repr
|
|
|
|
proc getFieldAndPragma(
|
|
fieldDef: NimNode
|
|
): tuple[fieldName, typeName: string, pragmaNode: NimNode] {.compileTime.} =
|
|
if fieldDef.kind != nnkIdentDefs:
|
|
return ("", "", newNimNode(nnkEmpty))
|
|
|
|
let declaredField = fieldDef[0]
|
|
var typeNode = fieldDef[1]
|
|
var pragmaNode = newNimNode(nnkEmpty)
|
|
|
|
if declaredField.kind == nnkPragmaExpr:
|
|
pragmaNode = declaredField[1]
|
|
elif typeNode.kind == nnkPragmaExpr:
|
|
pragmaNode = typeNode[1]
|
|
typeNode = typeNode[0]
|
|
|
|
return (getFieldName(declaredField), typeNode.repr, pragmaNode)
|
|
|
|
proc makeMetaNode(
|
|
fieldName, typeName, cliName, desc, defaultValue, command: string
|
|
): NimNode {.compileTime.} =
|
|
result = newTree(
|
|
nnkObjConstr,
|
|
ident("ConfigOptionMeta"),
|
|
newTree(nnkExprColonExpr, ident("fieldName"), newLit(fieldName)),
|
|
newTree(nnkExprColonExpr, ident("typeName"), newLit(typeName)),
|
|
newTree(nnkExprColonExpr, ident("cliName"), newLit(cliName)),
|
|
newTree(nnkExprColonExpr, ident("desc"), newLit(desc)),
|
|
newTree(nnkExprColonExpr, ident("defaultValue"), newLit(defaultValue)),
|
|
newTree(nnkExprColonExpr, ident("command"), newLit(command)),
|
|
)
|
|
|
|
macro extractConfigOptionMeta*(T: typedesc): untyped =
|
|
proc findFirstRecList(n: NimNode): NimNode {.compileTime.} =
|
|
if n.kind == nnkRecList:
|
|
return n
|
|
for child in n:
|
|
let found = findFirstRecList(child)
|
|
if not found.isNil:
|
|
return found
|
|
return nil
|
|
|
|
proc collectRecList(
|
|
recList: NimNode, metas: var seq[NimNode], commandCtx: string
|
|
) {.compileTime.} =
|
|
for child in recList:
|
|
case child.kind
|
|
of nnkIdentDefs:
|
|
let (fieldName, typeName, pragmaNode) = getFieldAndPragma(child)
|
|
if fieldName.len == 0:
|
|
continue
|
|
let cliName = block:
|
|
let n = getPragmaValue(pragmaNode, "name")
|
|
if n.len > 0: n else: fieldName
|
|
let desc = getPragmaValue(pragmaNode, "desc")
|
|
let defaultValue = getPragmaValue(pragmaNode, "defaultValue")
|
|
metas.add(
|
|
makeMetaNode(fieldName, typeName, cliName, desc, defaultValue, commandCtx)
|
|
)
|
|
of nnkRecCase:
|
|
let discriminator = child[0]
|
|
if discriminator.kind == nnkIdentDefs:
|
|
let (fieldName, typeName, pragmaNode) = getFieldAndPragma(discriminator)
|
|
if fieldName.len > 0:
|
|
let cliName = block:
|
|
let n = getPragmaValue(pragmaNode, "name")
|
|
if n.len > 0: n else: fieldName
|
|
let desc = getPragmaValue(pragmaNode, "desc")
|
|
let defaultValue = getPragmaValue(pragmaNode, "defaultValue")
|
|
metas.add(
|
|
makeMetaNode(fieldName, typeName, cliName, desc, defaultValue, commandCtx)
|
|
)
|
|
|
|
for i in 1 ..< child.len:
|
|
let branch = child[i]
|
|
case branch.kind
|
|
of nnkOfBranch:
|
|
let branchCtx = branch[0].repr
|
|
for j in 1 ..< branch.len:
|
|
if branch[j].kind == nnkRecList:
|
|
collectRecList(branch[j], metas, branchCtx)
|
|
of nnkElse:
|
|
for j in 0 ..< branch.len:
|
|
if branch[j].kind == nnkRecList:
|
|
collectRecList(branch[j], metas, commandCtx)
|
|
else:
|
|
discard
|
|
else:
|
|
discard
|
|
|
|
let typeInst = getTypeInst(T)
|
|
var targetType = T
|
|
if typeInst.kind == nnkBracketExpr and typeInst.len >= 2:
|
|
targetType = typeInst[1]
|
|
|
|
let typeImpl = getImpl(targetType)
|
|
let recList = findFirstRecList(typeImpl)
|
|
if recList.isNil:
|
|
return newTree(nnkPrefix, ident("@"), newNimNode(nnkBracket))
|
|
|
|
var metas: seq[NimNode] = @[]
|
|
collectRecList(recList, metas, "")
|
|
|
|
let bracket = newNimNode(nnkBracket)
|
|
for node in metas:
|
|
bracket.add(node)
|
|
|
|
result = newTree(nnkPrefix, ident("@"), bracket)
|