I'm getting the following error for the code below `(172, 9) Error: cannot prove that it's safe to initialize 'child' with the runtime value for the discriminator 'kind'`
I sort of understand the general idea, since the child of the NtmlElement is conditional, and since I am creating NtmlElement at compile time, the compiler must be able to determine before runtime whether the child will be of kind elementNode or textNode. What I don't understand is how to eliminate the uncertainty. import macros type NtmlNodeType = enum fragmentNode, h1Node, pNode, divNode NtmlElementType = enum elementNode, textNode NtmlProp = object of RootObj key: string value: string NtmlElement = object of RootObj nodeType: NtmlNodeType props: seq[NtmlProp] case kind: NtmlElementType of elementNode: children: seq[NtmlElement] of textNode: child: string macro generateNtml(tree: untyped): untyped = proc processNtml(tree: NimNode): NimNode = case tree.kind: of nnkStmtList: var fragmentChildren = newSeq[NimNode]() for branch in tree: fragmentChildren.add(processNtml(branch)) result = nnkObjConstr.newTree( newIdentNode("NtmlElement"), nnkExprColonExpr.newTree( newIdentNode("nodeType"), newIdentNode("fragmentNode") ), nnkExprColonExpr.newTree( newIdentNode("props"), nnkPrefix.newTree( newIdentNode("@"), nnkBracket.newTree() ) ), nnkExprColonExpr.newTree( newIdentNode("kind"), newIdentNode("elementNode") ), nnkExprColonExpr.newTree( newIdentNode("children"), nnkPrefix.newTree( newIdentNode("@"), nnkBracket.newTree(fragmentChildren) ) ) ) of nnkCall: var ntmlElement: NimNode var props = newSeq[NimNode]() var children = newSeq[NimNode]() var child = "" var nodeType: NtmlNodeType var elementType: NtmlElementType for branch in tree: if branch.kind == nnkIdent: case $branch of "dv": nodeType = divNode elementType = elementNode of "h1": nodeType = h1Node elementType = textNode of "p": nodeType = pNode elementType = textNode elif branch.kind == nnkExprEqExpr: props.add( nnkObjConstr.newTree( newIdentNode("NtmlProp"), nnkExprColonExpr.newTree( newIdentNode("key"), newLit($branch[0]) ), nnkExprColonExpr.newTree( newIdentNode("value"), newLit($branch[1]) ) ) ) elif branch.kind == nnkStmtList and elementType == elementNode: children.add(processNtml(branch)) elif branch.kind == nnkStmtList and elementType == textNode: for leaf in branch: child.add($leaf) return nnkObjConstr.newTree( newIdentNode("NtmlElement"), nnkExprColonExpr.newTree( newIdentNode("nodeType"), newIdentNode($nodeType) ), nnkExprColonExpr.newTree( newIdentNode("props"), nnkPrefix.newTree( newIdentNode("@"), nnkBracket.newTree(props) ) ), nnkExprColonExpr.newTree( newIdentNode("elementType"), newIdentNode($elementType) ), case elementType of elementNode: nnkExprColonExpr.newTree( newIdentNode("children"), nnkPrefix.newTree( newIdentNode("@"), nnkBracket.newTree(children) ) ) of textNode: nnkExprColonExpr.newTree( newIdentNode("child"), newLit(child) ) ) else: # add empty fragment here, code removed for brevity return processNtml(tree) let generatedNtml = generateNtml: dv: h1: "hello" p: "world" Run