///|
/// A single attribute of an XML start tag.
pub(all) struct Attribute {
  /// Raw qualified name, e.g. `"xmlns:itunes"` or `"href"`.
  key : String
  /// Entity-decoded value.
  value : String
} derive(Debug, Eq)

///|
/// A streaming XML event.
pub(all) enum Event {
  /// `` — an opening tag.
  Start(name~ : String, attrs~ : Array[Attribute])
  /// `` — a self-closing tag.
  Empty(name~ : String, attrs~ : Array[Attribute])
  /// `` — a closing tag.
  End(String)
  /// Character data with predefined and numeric entities decoded.
  Text(String)
  /// A `` section; contents are kept verbatim.
  CData(String)
  /// An XML comment.
  Comment(String)
  /// End of input. Repeated calls keep returning `Eof`.
  Eof
} derive(Debug, Eq)

///|
/// Errors raised while scanning malformed XML.
pub(all) suberror XmlError {
  /// Malformed markup at code-unit offset `pos`.
  Syntax(pos~ : Int, msg~ : String)
} derive(Debug, Eq)

///|
impl Show for XmlError with fn output(self, logger) -> Unit {
  match self {
    Syntax(pos~, msg~) =>
      logger.write_string("xml syntax error at offset \{pos}: \{msg}")
  }
}