Before this, a stream error would not be readable by user code, as the
`recv_features()` function would not even attempt to parse it. This
change allows application code to react to stream errors which are
received before stream features are received.
skip-changelog, because there's no release with the xmlstream module
yet.
The stream may have read some data already (such as the stream
header). When initially writing this code, I had missed that we do
actually also carry the parser state over: I misread the
AsyncReader::wrap(..) command as something like AsyncReader::new, i.e.
starting off with fresh parser state, so I assumed that we need a fresh
XmlLangStack, too.
This is wrong: `p` comes from `self.parser.into_inner()` above and is
the parser state, so we need to carry the lang stack along, as well.
This fixes:
```
thread 'tokio-runtime-worker' panicked at […]/rxml-0.13.1/src/xml_lang.rs:87:13:
pop from empty XmlLangStack
```
happening during stream shutdown. The panic was first reported by
@ppjet6, so thanks for that and the keen eye.
skip-changelog, because the bug has not been released yet.
This allows to use any serialisable type. The advantage is that moves
and clones are avoided (which would otherwise be needed to construct
e.g. a XmppStreamElement from a Stanza or Message).
First switch to LazyLock from OnceLock, to simplify the code.
Then concatenate the colour reset escape code instead of using
format!(), since the vast majority of those strings have more capacity
than their length it will avoid a reallocation in most cases.
This allows to detect and handle dying streams without getting stuck
forever.
Timeouts are always wrong, though, so we put the burden of choosing the
right values (mostly) on the creator of a stream.
Without the early return in XmlStream::poll_next in case of the stream
footer, the read state gets recreated and the logic at the top of that
function to actually handle stream shutdown gracefully is never
triggered.
Also that logic was incorrect; the correct behaviour is to wait for the
true EOF.
This makes the stream resets a lot safer, by preventing the forbidden
send-read-reset combination of events: the reset function on the
responder side now takes the element to send right before the reset,
enforcing a send-reset pattern.