Commit graph xmpp-rs/xso-proc/src/compound.rs
Author SHA1 Message Date
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
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
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
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
0361b5905b xso: implement catch-all for unknown elements 2024-08-05 15:33:57 +02:00
Jonas Schäfer
c7c180feb6 xso: implement support for defaulting extracts 2024-08-04 16:07:14 +02:00
Emmanuel Gil Peyrot
1828fde78c xso-proc: Use core instead of std wherever possible 2024-08-04 12:41:17 +00:00
Jonas Schäfer
df63c2a78f xso: allow omission of namespace and name on extracts
This is a quality-of-life improvement, as it may save lots of typing in
the common case (see the diff in parsers).
2024-08-03 15:25:46 +02:00
Jonas Schäfer
2c5f1f096b xso: implement support for extracting data from child elements 2024-08-03 15:17:30 +02:00
Jonas Schäfer
5efaabc74b xso-proc: allow constructing a Compound from processed fields
This will come in handy when we implement the ability to extract
data from nested children.
2024-08-03 15:17:30 +02:00
Jonas Schäfer
4845715add xso: implement support for enums 2024-08-01 15:28:22 +02:00
Jonas Schäfer
5bd36eccfc xso-proc: add support for child elements 2024-07-26 22:31:42 +02:00
Jonas Schäfer
ccf38cdf9b Port everything over to AsXml 2024-07-24 16:05:06 +02:00
Emmanuel Gil Peyrot
4356cab33c xso-proc: Fix all clippy warnings 2024-07-03 16:28:11 +02:00
Jonas Schäfer
c83ff286e0 xso-proc: add support for text codecs
Text codecs allow to customize the conversion of data from/to XML,
in particular in two scenarios:

1. When the type for which the behaviour is to be defined comes from a
   foreign crate, preventing the implementation of
   FromXmlText/IntoXmlText.

2. When there is not one obvious, or more than one sensible, way to
   convert a value to XML text and back.
2024-07-02 06:56:30 +02:00
Jonas Schäfer
46584f05f9 xso: refine handling of multiple #[xml(text)] fields
Previously, we only enforced the existence of at most one `#[xml(text)]`
field only at code generation time for `FromXml`. This change enforces
it at parsing time, which is more consistent and allows for a clearer
error message.
2024-07-01 08:01:42 +02:00
Jonas Schäfer
ae30221e3c xso: only fail on non-whitespace unknown text
We hereby ignore whitespace-only unexpected text, because that's
generally harmless.
2024-07-01 08:01:42 +02:00
Jonas Schäfer
b0803f831b xso-proc: add support for parsing text content 2024-07-01 08:01:42 +02:00
Jonas Schäfer
212c5c4a83 xso-proc: add support for parsing attributes into Strings
This is bare-bones and is missing many features which we intend to add
in future commits, such as parsing from attributes whose names differ
from the field names and parsing into non-String types.
2024-06-24 11:33:10 +02:00
Jonas Schäfer
183bef5cf6 xso-proc: completely overengineer everything for no good reason!
Well, not really, of course. All of this will make sense once we start
adding support for fields and non-struct types. Refactoring the code now
before we start to add actual member field parsing is much easier.

How do I know that this will work out? Well, my crystal ball knows it.
Don't believe me? Okay, ChatGPT told me ... Alright alright, I went
through the entire process of implementing this feature *twice* at this
point and have a pretty good idea of where to draw the abstraction lines
so that everything falls neatly into place. You'll have to trust me on
this one.

(Or, you know, check out old branches in my xmpp-rs repo. That might
work, too. `feature/derive-macro-streaming-full` might be a name to look
for if you dare.)
2024-06-23 18:43:34 +02:00