PureXML/Sources/XInclude/XIncludeError.swift
Mihaela Mihaljevic b13cdca739 feat(xinclude): content-negotiation hints, cycle detection, text+fragment
Three XInclude gaps from the audit:

- accept / accept-language / encoding are surfaced to the loader via a new
  XIncludeRequest and a process(_:base:loading:) overload, so a loader can
  honor content negotiation. The existing loadingURI form is kept.
- Cycle detection tracks the visited (resolved-URI) set along the current
  inclusion chain and raises XIncludeError.cycle, instead of relying only
  on the depth backstop; a non-cyclic diamond include is not flagged.
- parse="text" combined with an xpointer is rejected
  (XIncludeError.textWithFragment), since a fragment cannot select within
  unparsed text.

xpointer range() inclusion still depends on the XPointer range() scheme
(tracked in the XPointer issue).

Part of #87
2026-06-08 15:52:18 +02:00

27 lines
1.3 KiB
Swift

public extension PureXML.XInclude {
/// An error during XInclude processing.
enum XIncludeError: Swift.Error, Equatable, Sendable, CustomStringConvertible {
/// An `xi:include` had no `href` and no usable fallback.
case missingHref
/// The resource could not be loaded and there was no `xi:fallback`.
case unresolved(String)
/// Includes nested past the recursion limit (a likely include loop).
case toodeep
/// The same resource is included along its own inclusion chain.
case cycle(String)
/// `parse="text"` was combined with an `xpointer`/fragment, which selects a
/// subtree and so is meaningless for an unparsed text inclusion.
case textWithFragment
public var description: String {
switch self {
case .missingHref: "an xi:include has no href and no fallback"
case let .unresolved(href): "could not resolve xi:include href '\(href)' and no fallback"
case .toodeep: "xi:include nesting is too deep (possible loop)"
case let .cycle(uri): "xi:include forms a cycle including '\(uri)'"
case .textWithFragment: "xi:include with parse=\"text\" must not carry an xpointer"
}
}
}
}