// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0
///|
/// Why a document could not be read, or a query could not be run. One family
/// for the whole library, so there is one thing to catch.
pub(all) suberror Refused {
/// The input is not well-formed where it must be: `at` is the offset in the
/// input, counted in UTF-16 code units as `String::length` counts them.
Malformed(at~ : Int32, why~ : String)
/// A selector or XPath expression does not parse; `at` is the offset in the
/// query itself.
BadQuery(at~ : Int32, why~ : String)
/// `selector(name, ..)` was called with a name nobody registered.
UnknownSelector(name~ : String)
/// A named gap rather than a syntax error: an XPath variable with no
/// binding, and the like.
Unsupported(what~ : String)
/// The input went past a configured bound: `got` against `limit`, noticed at
/// offset `at`.
Exceeded(at~ : Int32, limit~ : Int32, got~ : Int32)
} derive(Eq, Debug)
///|
pub extend Refused with Eq::{equal, not_equal}
///|
pub extend Refused with Debug::{to_repr}
///|
pub impl Show for Refused with fn output(self, logger) {
logger.write_string(
match self {
Malformed(at~, why~) => "malformed at \{at}: \{why}"
BadQuery(at~, why~) => "bad query at \{at}: \{why}"
UnknownSelector(name~) => "no selector registered as \{name}"
Unsupported(what~) => "unsupported: \{what}"
Exceeded(at~, limit~, got~) =>
"\{got} exceeds the limit of \{limit} at \{at}"
},
)
}
///|
pub extend Refused with Show::{output, to_string}
///|
/// What the HTML parser repaired. WHATWG says repairs happen silently; this
/// tally makes them answerable afterwards, for a caller who wants to ask.
pub(all) struct Repairs {
mut implied : Int32
mut dropped : Int32
mut reparented : Int32
mut closed_at_eof : Int32
}
///|
/// A tally with nothing in it.
pub fn Repairs::new() -> Repairs {
{ implied: 0, dropped: 0, reparented: 0, closed_at_eof: 0, }
}
///|
/// Every repair the parser made, added up.
pub fn Repairs::total(self : Repairs) -> Int32 {
self.implied + self.dropped + self.reparented + self.closed_at_eof
}
///|
/// Whether the parser repaired anything at all.
pub fn Repairs::any(self : Repairs) -> Bool {
self.total() > 0
}