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.
These more closely mirror how enums work currently with the macros.
Non-exhaustive enums may be useful though and kind of were the natural
thing to implement.
Previously, if you put `codec = FixedHex<20>.filtered(..)`, it would
cause a confusing "expected `,`" message at the place of the `.`. This
code adds a helpful "try adding a `::` before the `<`" message pointing
at the `<` in the type path.
We can do this because we know that `x < y` cannot create a
`TextCodec<T>` for any `T`. This is because `<` is guaranteed to return
a boolean value, and we simply don't implement `TextCodec<T>` on bool.
This allows stateful or configurable codecs without having to express
all configuration in the type name itself. For example, we could have a
Base64 type with configurable Base64 engines without having to duplicate
the Base64 type itself.
(Note that the different engines in the Base64 crate are values, not
types.)
By removing that, the lint won't trigger for identifiers with trailing
underscores (which become then embedded underscores which normally trips
the `non_camel_case_types` lint).
In 1265f4b, we introduced a change which may cause a conflict of type
names when deriving the traits on two different types. While a
workaround existed (use `mod`s to isolate the implementation), that is
ugly.
This commit allows overriding the choice of type names.
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.
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.
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.
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.)