preserves-nim/src/preserves/xmlhooks.nim

56 lines
1.7 KiB
Nim
Raw Normal View History

2021-12-06 23:28:00 +00:00
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[xmltree, strtabs, tables]
import ../preserves
proc toPreserveHook*(xn: XmlNode; E: typedesc): Preserve[E] =
if xn.kind == xnElement:
result = Preserve[E](kind: pkRecord)
2021-12-06 23:28:00 +00:00
if not xn.attrs.isNil:
var attrs = initDictionary[E]()
2021-12-06 23:28:00 +00:00
for key, val in xn.attrs.pairs:
attrs[toPreserve(key, E)] = toPreserve(val, E)
result.record.add(attrs)
for child in xn.items:
case child.kind
of xnElement:
result.record.add(toPreserveHook(child, E))
of xnText, xnVerbatimText, xnCData, xnEntity:
result.record.add(toPreserve(child.text, E))
of xnComment:
discard
result.record.add(toSymbol(xn.tag, E))
proc toString(pr: Preserve): string =
case pr.kind
of pkString: pr.string
of pkBoolean:
if pr.bool: "true" else: "false"
else: $pr
2021-12-06 23:28:00 +00:00
proc fromPreserveHook*[E](xn: var XmlNode; pr: Preserve[E]): bool =
if pr.kind == pkRecord and pr.label.kind == pkSymbol:
xn = newElement($pr.label)
var i: int
for e in pr.fields:
if i == 0 and e.kind == pkDictionary:
var pairs = newSeqOfCap[tuple[key, val: string]](e.dict.len)
for key, val in e.dict.items:
pairs.add((key.toString, val.toString,))
xn.attrs = pairs.toXmlAttributes
elif e.kind == pkString:
xn.add newText(e.string)
2021-12-06 23:28:00 +00:00
else:
var child: XmlNode
result = fromPreserveHook(child, e)
if not result: return
xn.add child
inc i
result = true
2021-12-06 23:28:00 +00:00
when isMainModule:
var xn = XmlNode()
var pr = xn.toPreserveHook(void)
assert fromPreserveHook(xn, pr)