Compare commits

...

2 Commits

Author SHA1 Message Date
Emery Hemingway e25e06efba Don't convert Table[string,string] to {symbol:string...:...}
Should not assume that table keys can be treated at symbols. This
also makes the resulting dictionary convertable to JSON.
2021-12-22 23:49:06 +01:00
Emery Hemingway 84b28ec55a XML: use tuples rather than records for elements 2021-12-22 22:27:18 +01:00
2 changed files with 32 additions and 29 deletions

View File

@ -748,7 +748,7 @@ proc toPreserveHook*[A, B](table: Table[A, B]|TableRef[A, B], E: typedesc): Pres
result = initDictionary[E]()
for k, v in table.pairs:
when A is string:
result[toSymbol(k, E)] = toPreserve(v, E)
result[toPreserve(k, E)] = toPreserve(v, E)
else:
result[toPreserve(k, E)] = toPreserve(v, E)

View File

@ -7,18 +7,20 @@ import ../preserves
proc toPreserveHook*(xn: XmlNode; E: typedesc): Preserve[E] =
case xn.kind
of xnElement:
var children = initSequence[E](xn.len)
var i: int
for child in xn.items:
children[i] = toPreserveHook(child, E)
inc i
var attrMap = initDictionary[E]()
result = initSequence[E](xn.len + 2)
result[0] = toSymbol(xn.tag, E)
var attrs = initDictionary[E]()
if not xn.attrs.isNil:
for key, val in xn.attrs.pairs:
attrMap[toSymbol(key, E)] = toPreserve(val, E)
result = initRecord[E](xn.tag, attrMap, children)
attrs[toPreserve(key, E)] = toPreserve(val, E)
result[1] = attrs
var i = 2
for child in xn.items:
result[i] = toPreserveHook(child, E)
inc i
of xnText:
result = toPreserve(xn.text, E)
result = initSequence[E](1)
result[0] = toPreserve(xn.text, E)
of xnVerbatimText:
result = initRecord[E]("verbatim", xn.text.toPreserve(E))
of xnComment:
@ -30,28 +32,29 @@ proc toPreserveHook*(xn: XmlNode; E: typedesc): Preserve[E] =
proc fromPreserveHook*[E](xn: var XmlNode; pr: Preserve[E]): bool =
case pr.kind:
of pkString:
xn = newText(pr.string)
result = true
of pkRecord:
if pr.len == 2 and pr[0].isDictionary and pr[1].isSequence and pr.label.isSymbol:
xn = newElement(pr[2].symbol)
of pkSequence:
if pr.len == 1 and pr[0].isString:
xn = newText(pr[0].string)
result = true
if pr[0].len > 0:
var attrs = newStringTable()
for key, val in pr[0].dict.items:
if not (key.isSymbol and val.isString):
elif pr.len >= 2 and pr[0].isSymbol and pr[1].isDictionary:
result = true
var children = newSeq[XmlNode](pr.len - 2)
for i in 2..<pr.len:
result = fromPreserve(children[i-2], pr[i])
if not result: break
var attrs: XmlAttributes
if pr[1].len > 0:
attrs = newStringTable()
for key, val in pr[1].dict.items:
if key.isString and val.isString:
attrs[key.string] = val.string
else:
result = false
break
attrs[key.symbol] = val.string
xn.attrs = attrs
var child: XmlNode
for e in pr[1]:
result = fromPreserveHook(child, e)
if not result: break
xn.add(move child)
if not result: reset xn
elif pr.len == 1 and pr.label.isSymbol:
if result:
xn = newXmlTree(pr[0].symbol, children, attrs)
of pkRecord:
if pr.len == 1 and pr[0].isString and pr.label.isSymbol:
result = true
case pr.label.symbol:
of "verbatim":