Skip to content

Commit

Permalink
fix(xml): use the type system to verify version
Browse files Browse the repository at this point in the history
Reverts: 78ed4ac
  • Loading branch information
lishaduck committed Jun 6, 2024
1 parent 52d3ad2 commit 559f980
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
6 changes: 4 additions & 2 deletions xml/_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ export type xml_node = {
[key: string]: unknown
}

export type v1_x = `1.${number}`

/** XML document. */
export type xml_document = xml_node & {
export type xml_document<version extends v1_x = v1_x> = xml_node & {
/** XML version. */
["@version"]?: string
["@version"]?: version
/** XML character encoding. */
["@encoding"]?: string
/** XML standalone. */
Expand Down
17 changes: 17 additions & 0 deletions xml/_types_test.ts
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
import "./_types.ts"
import { stringify } from "./mod.ts"

// Verify that the generic type is correctly inferred.
const _example = stringify({
"@version": "1.1",
"@encoding": "UTF-8",
"@standalone": "yes",
"#doctype": {
"~name": "html",
"~children": [],
"#text": "",
},
"#instructions": {},
"~name": "html",
"~children": [],
"#text": "",
})
10 changes: 5 additions & 5 deletions xml/stringify.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Imports
import type { Nullable, record, rw } from "@libs/typing"
import type { xml_document, xml_node, xml_text } from "./_types.ts"
import type { v1_x, xml_document, xml_node, xml_text } from "./_types.ts"

// Re-exports
export type { xml_document, xml_node, xml_text }
Expand Down Expand Up @@ -63,15 +63,15 @@ const internal = Symbol("internal")
* }))
* ```
*/
export function stringify(document: Partial<xml_document>, options?: options): string {
export function stringify<const V extends v1_x>(document: Partial<xml_document<V>>, options?: options): string {
options ??= {}
options.format ??= {}
options.format.indent ??= " "
options.format.breakline ??= 128
const _options = options as _options
let text = ""
// Add prolog
text += xml_prolog(document as xml_document, _options)
text += xml_prolog(document as xml_document<V>, _options)
// Add processing instructions
if (document["#instructions"]) {
for (const nodes of Object.values(document["#instructions"])) {
Expand All @@ -86,7 +86,7 @@ export function stringify(document: Partial<xml_document>, options?: options): s
}

// Add root node
const [root, ...garbage] = xml_children(document as xml_document, _options)
const [root, ...garbage] = xml_children(document as xml_document<V>, _options)
if (garbage.length) {
throw new SyntaxError("Multiple root node detected")
}
Expand All @@ -112,7 +112,7 @@ export function comment(text: string): Omit<xml_text, "~parent"> {
}

/** Create XML prolog. */
function xml_prolog(document: xml_document, options: _options): string {
function xml_prolog<const V extends v1_x>(document: xml_document<V>, options: _options): string {
;(document as rw)["~name"] ??= "xml"
return xml_instruction(document, options)
}
Expand Down

0 comments on commit 559f980

Please sign in to comment.