Commit graph xmpp-rs/xso-proc
Author SHA1 Message Date
Jonas Schäfer
1710a6f99e Release all crates
Since we tie the versions rather tightly, we have to release the entire
bunch in order to allow people to upgrade to rxml 0.14.
2026-06-11 17:25:32 +02:00
Jonas Schäfer
bb02836097 Bump rxml to 0.14.0 2026-02-21 13:56:50 +01:00
pep
00b638fc38 xso{,-proc}: clippy
This doesn't fix all of the clippy warnings in these crates. There are
decisions that needs to be made in there that I'm not willing to make.

Signed-off-by: pep <pep@bouah.net>
2025-11-01 16:30:22 +01:00
Jonas Schäfer
ccdf27117d Fix docs build with current nightly
skip-changelog, we don't officially support nightly.

See-Also: https://github.com/rust-lang/rfcs/pull/3631
See-Also: https://github.com/rust-lang/rust/pull/138907
2025-10-08 13:03:39 +02:00
Jonas Schäfer
5ab4f395e0 Bump xso_proc version to 0.2.0
skip-changelog, we do not keep a dedicated changelog for xso-proc.
2025-09-17 19:29:39 +02:00
Jonas Schäfer
59af49c691 xso-proc: provide FromXml::xml_name_matcher on derived impls
That way, derived implementations can also make use of the performance
benefits.
2025-07-13 11:10:51 +00:00
Jonas Schäfer
8d8a19380a xso-proc: avoid an ambiguous_associated_items error
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
2025-05-13 12:01:21 +00:00
Jonas Schäfer
4c47946b81 xso-proc: update inline comment with resolution from upstream bug
Reminder: when something feels too good to be true, it likely is.

skip-changelog, because this is no user-facing change.
2025-05-03 17:57:15 +02:00
Jonas Schäfer
de39f410d5 xso-proc: improve spans for error messages
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 ...
2025-05-02 17:16:59 +02:00
Jonas Schäfer
2a940fb5e0 xso-proc: work around regression in rustc nightly
skip-changelog, this is no user-facing change.

See-Also: https://github.com/rust-lang/rust/issues/140585
2025-05-02 16:29:58 +02:00
Jonas Schäfer
c0262fbafb xso: add support for attribute-switched enums
skip-changelog, because enums have been introduced in the same release,
so this is merely an addition to the already changelogged enum feature.
2025-04-27 18:34:48 +00:00
Jonas Schäfer
f4b981dc78 xso-proc: allow injecting states into the AsItemsSubmachine
This is useful if constant data is to be emitted into the element
header and a prerequisite for attribute-switched enums.
2025-04-27 18:34:48 +00:00
Jonas Schäfer
847032ed35 xso-proc: add support for matching elements using match
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.
2025-04-27 18:34:48 +00:00
Jonas Schäfer
67f3ffaced xso: re-implement #[xml(lang)] on top of #[xml(attribute)]
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.
2025-04-27 14:19:31 +02:00
Jonas Schäfer
9fdb1564f6 xso: reject attempts to match the same XML attribute in different fields
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.
2025-04-27 11:18:50 +02:00
Jonas Schäfer
d9a21dd8c9 Track xml:lang throughout parsing 2025-04-22 17:55:44 +02:00
Jonas Schäfer
31d7bbf622 xso: discard xml:lang implicitly
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.
2025-04-22 17:55:12 +02:00
Jonas Schäfer
0fd69d2ff8 xso-proc: fix order-dependent compilation bug
The test case which is added fails to compile unless one puts the
`parent` field before the `id` field. The cause is explained somewhat by
the change, but I'll spell it out here nontheless.

Previously, the loop in `Compound::make_as_item_iter_statemachine`
assumed that the serialisation order of fields would match their
declaration order. That is not generally true: attributes must be
serialised before element content, because they must be emitted before
the element header is closed.

This change thus splits the generated states into "header" states (for
everything before the end of the element header (think `>`)) and
"body" states (for everything after and including the end of the
element header). After all fields have been processed, we can then
add the data fields of the body fields to the header states so that
they are carried through the generated state machine until they are
needed in the body.
2025-04-18 12:41:12 +02:00
Jonas Schäfer
8e81c41f59 xso: add support for post-deserialization callback 2025-04-18 10:49:26 +02:00
Maxime “pep” Buquet
4994ac20f9 xso-proc: clippy run
Caught a bug hidden behind #[cfg(not(feature = "minidom"))]

Signed-off-by: Maxime “pep” Buquet <pep@bouah.net>
2025-04-08 12:47:56 +02:00
Jonas Schäfer
b05ee0280a xso: add support for selectively discarding text and attributes 2025-04-06 08:36:15 +02:00
Jonas Schäfer
4148e9d165 xso-proc: hide generated FromXml / AsXml types
They really clutter the documentation, because they show up in the
module's index. Downside is that users can't inspect the documentation
of those types anymore, but it's not useful anyway: the parts are
private and they just impl some traits.
2025-01-28 18:26:55 +01:00
Emmanuel Gil Peyrot
1823afbc71 xso-proc: Add the default flag to the element meta
This allows the payload to be absent, and requires the field type to be
Option<minidom::Element>.
2025-01-26 16:40:05 +00:00
Emmanuel Gil Peyrot
c72cf3ddd1 xso-proc: Add n = 1 flag to element meta
This allows exactly one arbitrary payload in any element, and is handled
after every other element with a more specific matcher has been parsed.

Both the #[xml(element(n = 1))] meta and its shortcut #[xml(element)]
are allowed and treated the exact same way.
2025-01-26 16:40:05 +00:00
Jonas Schäfer
beae4ae66b xso: fix no_std support
This reverts the Revert in 6ec275d3 which had to be done in order to
un-break usage of xso in std crates.
2025-01-26 15:07:17 +00:00
Jonas Schäfer
bf12accd48 xso-proc: improve NestedMatcher documentation
skip-changelog
2025-01-26 14:00:48 +00:00
Emmanuel Gil Peyrot
fefc898fdf xso-proc: Allow #[xml(flag)] without params
The namespace defaults to the parent’s namespace, and the name to the
field name, so we can avoid needlessly duplicating that info.
2025-01-25 20:07:47 +01:00
Emmanuel Gil Peyrot
01a0c51a2f xso-proc: Add support for the codec field on attribute meta
This allows a custom TextCodec to be used for encoding and decoding the
attribute’s value, instead of FromXmlText and AsOptionalXmlText.
2025-01-25 18:07:44 +01:00
Jonas Schäfer
95773505e4 xso-proc: improve error message on type mismatch for extracted fields
The case this affects is a field like:

```
struct Foo {
   #[xml(extract(fields(text(type_ = String)), namespace = .., name = ..))]
   foo: ServiceType,
}
```

Before, we get this:

```
error[E0631]: type mismatch in closure arguments
    --> muchopper/libmuchopper/src/xmpp/sjn_api.rs:188:10
     |
188  | #[derive(AsXml)]
     |          ^^^^^
     |          |
     |          expected due to this
     |          found signature defined here
     |
     = note: expected closure signature `fn(&ServiceType) -> _`
                found closure signature `fn(&'xso_proc_as_xml_iter_lifetime std::string::String) -> _`
note: required by a bound in `std::option::Option::<T>::map`
    --> /home/jssfr/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1102:12
     |
1100 |     pub fn map<U, F>(self, f: F) -> Option<U>
     |            --- required by a bound in this associated function
1101 |     where
1102 |         F: FnOnce(T) -> U,
     |            ^^^^^^^^^^^^^^ required by this bound in `Option::<T>::map`
     = note: this error originates in the derive macro `AsXml` (in Nightly builds, run with -Z macro-backtrace for more info)

```

Afterwards, this:

```
error[E0308]: mismatched types
   --> muchopper/libmuchopper/src/xmpp/sjn_api.rs:207:20
    |
206 |     #[xml(extract(namespace = ECS, name = "service-type", fields(text(type_ = String))))]
    |                                                                               ------ expected due to this
207 |     pub service_type: ServiceType,
    |                       ^^^^^^^^^^^ expected `Option<&String>`, found `Option<&ServiceType>`
    |
    = note: expected enum `std::option::Option<&'xso_proc_as_xml_iter_lifetime std::string::String>`
               found enum `std::option::Option<&ServiceType>`

```

skip-changelog, because this affects a feature which already has an
"Added" line in the changelog.
2025-01-24 18:28:52 +01:00
Jonas Schäfer
727e57b756 Implement #[xml(flag)] meta 2025-01-21 19:12:43 +01:00
Jonas Schäfer
6ec275d381 Revert "xso-proc: Replace std stuff with alloc/core stuff"
This reverts commit 4e5f0bc961.

Unfortunately, in std contexts, the `alloc` crate is not imported. That
means we cannot rely on it being accessible and it in fact breaks builds
of crates which are not `no_std`.

Fixes #155.
2025-01-20 17:52:35 +01:00
Jonas Schäfer
58698f633f xso: only take reference in transform
This avoids the need for an expensive clone. Since we switched to AsXml
instead of IntoXml, we don't necessarily have to clone the data when
building new elements, only when it's absolutely necessary. The clones
then happen implicitly in the ItemToEvent iterator used internally.

This mostly fixes #86, with the caveat that there's no absolutely cheap
test: On success, the entire element will be copied, while on failure,
you learn about it rather quickly.
2024-12-20 12:44:43 +01:00
4e5f0bc961 xso-proc: Replace std stuff with alloc/core stuff 2024-12-19 20:51:56 +01:00
Jonas Schäfer
7d8ffe45a7 xso: add support for ignoring unknown stuff in extracts 2024-10-26 17:37:32 +00:00
Jonas Schäfer
66233b0150 xso: add support for ignoring unknown children 2024-10-26 17:37:32 +00:00
Jonas Schäfer
290460ba9d xso: add support for ignoring unknown attributes 2024-10-26 17:37:32 +00:00
Alvaro Parker
2ff89a9e42 fix typos 2024-09-16 18:29:44 -03:00
Jonas Schäfer
c01eb090b8 xso-proc: improve error messages on cast mismatch for extracts
The old error message was pointing at the `FromXml` / `AsXml` invocation
and not on the field which actually caused the problem. The new error
message points exactly at the type of the affected field.
2024-08-31 10:50:44 +02:00
Jonas Schäfer
6b4886857e xso: offer is_xml_whitespace function 2024-08-12 12:32:12 +02:00
Jonas Schäfer
1ecb95881c xso: add support for extracting tuples 2024-08-11 07:58:12 +02:00
Jonas Schäfer
f1ab857c6e xso: move helper iterators and builders into separate module
This declutters the main `xso` namespace. In addition, if (when) we
introduce more complex generic implementations, we might want to have
tests for these, and those can then live there, too, without making the
main `lib.rs` file gigantic (or moving the tests too far away from the
tested code).
2024-08-11 07:45:05 +02:00
Jonas Schäfer
fb80bb7532 xso: add support for dynamic enums 2024-08-08 15:25:40 +00:00
Jonas Schäfer
b36d1d0d4c xso-proc: refactor enum handling
This will allow other kinds of enumerations in the future more
easily.
2024-08-08 15:25:40 +00:00
Jonas Schäfer
fda4a9ff29 xso: implement transparent structs 2024-08-05 15:13:39 +00:00
Jonas Schäfer
656125a850 xso-proc: change field def's span slightly for better UX 2024-08-05 15:33:57 +02:00
Jonas Schäfer
0361b5905b xso: implement catch-all for unknown elements 2024-08-05 15:33:57 +02:00
fa99c09585 Indicate which feature flag for each module/type 2024-08-05 11:14:41 +02:00
Jonas Schäfer
2358c8636e xso-proc: refactor field implementations into separate files
This decreases indentation levels on the various implemenations, it
groups the implementations together physically, and (spoiler alert!)
we'll actually need the dyn Field trait object-ness (much) later on.
2024-08-04 16:14:47 +02:00
Jonas Schäfer
19be14cdd8 xso-proc: make field into a module folder
This is in prepraration of more refactoring to come, in order to make
the individual field implementations easier to grok and look at.
2024-08-04 16:11:31 +02:00
Jonas Schäfer
b0996e3a35 xso-proc: pull out the extract code into a separate impl
This should make everything a little easier to read, because it reduces
the level of indentation involved.
2024-08-04 16:11:19 +02:00