PureXML/Sources/XPath/QueryError.swift
Mihaela Mihaljevic ac85dd36de feat(xpath,xslt,wasm): evaluation budget, tailored collation, WASI runtime proof
PureXML.XPath.Budget is the configurable counterpart of libxml2's
fixed 10M node-set cap (libxml2Compatible preset included), thrown as
a located QueryError instead of a silent refusal, default unbounded.
xsl:sort honors lang with tailored alphabet orders for Polish and
Russian derived from the conformance golds, case-folded. The WASM
gate executes all 985 tests under wasmtime on an actual WASI runtime,
wired into CI; the first run caught a real wasm32 trap (Int is 32
bits there, so format-number's digit extraction trapped at 2^31
despite the 2^53 guard; internals are now Int64 and the xsl:number
bound is platform-correct). Xalan baseline 127 -> 125. Closes #143,
closes #144.
2026-06-11 06:26:13 +02:00

37 lines
1.7 KiB
Swift

public extension PureXML.XPath {
/// An error compiling or evaluating an XPath query.
enum QueryError: Swift.Error, Equatable, Sendable, CustomStringConvertible {
case empty
/// The evaluation budget was exceeded (``PureXML/XPath/Budget``):
/// a node-set grew past the configured maximum.
case budgetExceeded(Int)
case unexpectedToken(String)
case expectedNodeTest
case unterminatedPredicate
case unsupportedPredicate(String)
/// An axis name was not one of the thirteen XPath axes.
case unsupportedAxis(String)
/// A function was called that is not in the library.
case unknownFunction(String)
/// A `$name` reference had no binding in the evaluation context.
case undefinedVariable(String)
/// A function received the wrong number or type of arguments.
case invalidArguments(String)
public var description: String {
switch self {
case .empty: "the XPath expression is empty"
case let .budgetExceeded(cap): "the evaluation budget was exceeded (node-set cap \(cap))"
case let .unexpectedToken(token): "unexpected token '\(token)'"
case .expectedNodeTest: "expected a node test"
case .unterminatedPredicate: "unterminated predicate"
case let .unsupportedPredicate(detail): "unsupported predicate: \(detail)"
case let .unsupportedAxis(axis): "unsupported axis: \(axis)"
case let .unknownFunction(name): "unknown function '\(name)()'"
case let .undefinedVariable(name): "variable '$\(name)' is not bound"
case let .invalidArguments(detail): "invalid arguments: \(detail)"
}
}
}
}