This was forgotten in 0f0759b207.
That element is only specified in the XML schema, its semantics aren’t
defined anywhere, but we can guess them anyway.
The only missing check is that #[xml(element)] doesn’t support filtering
on elements with a specific name yet.
skip-changelog: This isn’t a user-visible change.
Stop parsing xml:lang manually, instead use the #[xml(lang)] meta which
tracks it using the XML semantics, inheriting it from the most recent
ancestor.
skip-changelog: This isn’t a user-facing change.
rustc forbids cases where an enum variant and an associated type of a
trait conflict for a while now [1].
We must thus avoid referring to associated items on types we do not
control in the macros. There was only one case I found, and it was in
the TryFrom implementation, and could be easily resolved by explicitly
spelling out Self::Error.
[1]: https://github.com/rust-lang/rust/issues/57644
This provides a clear and consistent interface for selecting TLS-related
features on both (xmpp and tokio-xmpp) crates. All feature checks have
been revamped. All working combinations have been tested (including a
connectivity test + --all-features docs build) using:
```
set -xeuo pipefail
features=(aws_lc_rs ring ktls,aws_lc_rs ktls,ring aws_lc_rs,ring aws_lc_rs,ring,ktls native-tls rustls-any-backend)
export RUSTFLAGS=" -D warnings"
cargo test --no-default-features
cargo test
for feature in ${features[@]}; do
echo ">>> BUILDING with $feature" 2>&1
# Running code or building examples cannot succeed with rustls-any-backend.
features="starttls,$feature"
if [ "$feature" != 'rustls-any-backend' ]; then
if ! cargo test --no-default-features --features="$features"; then
echo ">>> BUILD FAILED for tls feature set: $features" >&2
exit 1
fi
set +e
timeout -sINT -p -k 2 3 cargo run --no-default-features --features="$features" --example keep_connection -- test@hub.sotecware.net "$(pass xmpp/test@hub.sotecware.net)"
status="$?"
set -e
if [ $status -ne 0 ]; then
echo ">>> keep_connection did not shut down cleanly! (status: $status)" >&2
exit 1
fi
else
if ! cargo build --no-default-features --features="$feature"; then
echo ">>> BUILD FAILED for tls feature set: $features" >&2
exit 1
fi
fi
done
RUSTDOCFLAGS="--cfg docsrs" RUSTFLAGS="--cfg xmpprs_doc_build" cargo +nightly doc -Zrustdoc-map --all-features
```
For this, we had to:
- Make the choice(s) of backend explicit in tokio-xmpp features
- Avoid picking a backend through transitive dependencies in xmpp
(reqwest->hyper->rustls).
In addition, we choose the default rustls backend by default and adapt
the examples so that they can cope with either situation.
This way, we don't end up with breakage if rustls is built with more
than one provider enabled. This can (and does) happen if a transitive
dependency (such as reqwest *hinthint*) depends on a specific,
non-default rustls backend.
The user may have to call some global rustls functions depending on the
exact feature set of rustls enabled. Hence, we have to expose it.
Concretely, if the user somehow ends up with more than one rustls
backend, they have to configure one of the backends as default backend
at startup.
The main lib.rs is getting a bit cluttered, so I'm trying to bring some
order into the chaos by moving some things into other modules.
skip-changelog, because there are no user-facing changes (names which
have been moved are doc(inline)'d and pub use'd in the main lib, and
other things (trait implementations) aren't addressable by users).
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.
So far this new meta doesn’t work for the BTreeMap<Lang, String>
pattern, which is often used to provide multiple versions of a payload.
skip-changelog: This isn’t a user-facing change.
For codec-based error messages, this reduces the amount of errors per
violation to one. For all others, it improves the placement of the error
slightly, but we still get duplicates.
I couldn't figure out the remaining discrepancies in the spans ...
The `match` expression will have to be provided by the caller. Use cases
could be to express the `NameSwitchedEnum` more clearly (by switching on
the XML element's name) or introducing new kinds of switched enums.
This gives us all the goodies of `default`, `type_` and `codec` without
having to duplicate lots of code (and I think the `match`-iness of the
new macro code is still within limits).
However, we still keep them as separate `#[xml(..)]` attributes, because
their semantics are very different and it is sensible to make them stand
out.
skip-changelog, because `#[xml(lang)]` was introduced in this version.
Using `#[doc(inline)]` there makes it appear in two places in the
documentation, which may be confusing (as it's not fully obvious that
both places are in fact the same trait).
The previous wording was a bit ominous in places ("Because of the
unfortunate situation as described in `FromXmlText`"). This should be
clearer and provides hopefully clearer instructions.
It is not necessary anymore, because we switched from `IntoXml` to
`AsXml`, allowing `transform` to work with a reference instead of
consuming its input.
Before that, `try_from_element` was the only way to fallibly attempt to
parse something from `Element` without having to clone the entire DOM.
This was a bit tricky to build, because it is possible to have an
indirection through a `static` there. Thanks to Rust's extensive
const-fn capabilities, though, it's in fact possible to cover all cases.
We still do two different checks to improve user experience. If we can,
from within the proc macro, determine that two fields refer to the same
XML attribute (because their namespace/name values use the same Rust
tokens), then we reject the fields with a clear error message pointing
at both fields.
In the other case, when there's e.g. `#[xml(lang)]` and
`#[xml(attribute(namespace = rxml::XMLNS_XML, name = "lang"))]`, the
macro cannot be sure that XMLNS_XML is in fact the XML namespace. For
that case, we generate code which is evaluated at compile time (and
has no runtime impact) which panics if the namespace and name of two
attribute-matching fields is the same.
The error message will be less clear (because it contains extra,
unchangeable wording like "evaluation of constant value failed" and "the
evaluated program panicked at", which may be a bit confusing) than the
message generated by the macros themselves, but it's a price we have to
pay unfortunately.
Note that this check may seem cosmetic and purely for better user
experience, but it is in fact needed to avoid generating not-well-formed
and/or not-namespace-well-formed XML: As `AsXml` generates `xso::Item`,
where each attribute is emitted separated (and not aggregated in a
map structure), a naive (and efficient) implementation of a writer might
not double-check that no duplicate attributes are generated.
Because this attribute may occur in random places, it makes no sense
failing on it. We discard it after attribute processing though, so it
can still be captured by structs which are explicitly interested in it.
This is still far from being a full fix. Still, we can avoid the lang
attribute (by allowing discarding the `xml:lang` value via the feature
introduced a couple commits ago) and we can avoid emitting `xml:lang=""`
where no language was previously set using the mechanism introduced for
<message/> in 5172fb5e.