enum ValueSource {
Unknown,
Attribute(Range<usize>),
Text,
Content,
Nested,
}
Expand description
Defines a source that should be used to deserialize a value in the next call
to next_value_seed()
Variants§
Unknown
Source are not specified, because next_key_seed()
not yet called.
This is an initial state and state after deserializing value
(after call of next_value_seed()
).
Attempt to call next_value_seed()
while accessor in this state would
return a DeError::KeyNotRead
error.
Attribute(Range<usize>)
Next value should be deserialized from an attribute value; value is located at specified span.
Text
Value should be deserialized from the text content of the XML node, which represented or by an ordinary text node, or by a CDATA node:
<any-tag>
<key>text content</key>
<!-- ^^^^^^^^^^^^ - this will be used to deserialize map value -->
</any-tag>
<any-tag>
<key><![CDATA[cdata content]]></key>
<!-- ^^^^^^^^^^^^^ - this will be used to deserialize a map value -->
</any-tag>
Content
Next value should be deserialized from an element with an any name, except
elements with a name matching one of the struct fields. Corresponding tag
name will always be associated with a field with name VALUE_KEY
.
That state is set when call to peek()
returns a Start
event, which
name()
is not listed in the list of known fields (which for a struct
is a list of field names, and for a map that is an empty list), and
struct has a field with a special name VALUE_KEY
.
When in this state, next event, returned by next()
, will be a Start
,
which represents both a key, and a value. Value would be deserialized from
the whole element and how is will be done determined by the value deserializer.
The ElementMapAccess
do not consume any events in that state.
Because in that state any encountered <tag>
is mapped to the VALUE_KEY
field, it is possible to use tag name as an enum discriminator, so enum
s
can be deserialized from that XMLs:
<any-tag>
<variant1>...</variant1>
<!-- ~~~~~~~~ - this data will determine that this is Enum::variant1 -->
<!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
</any-tag>
<any-tag>
<variant2>...</variant2>
<!-- ~~~~~~~~ - this data will determine that this is Enum::variant2 -->
<!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
</any-tag>
both can be deserialized into
enum Enum {
variant1,
variant2,
}
struct AnyName {
#[serde(rename = "$value")]
field: Enum,
}
That is possible, because value deserializer have access to the full content
of a <variant1>...</variant1>
or <variant2>...</variant2>
node, including
the tag name.
Nested
Next value should be deserialized from an element with a dedicated name. If deserialized type is a sequence, then that sequence will collect all elements with the same name until it will be filled. If not all elements would be consumed, the rest will be ignored.
That state is set when call to peek()
returns a Start
event, which
name()
represents a field name. That name will be deserialized as a key.
When in this state, next event, returned by next()
, will be a Start
,
which represents both a key, and a value. Value would be deserialized from
the whole element and how is will be done determined by the value deserializer.
The ElementMapAccess
do not consume any events in that state.
An illustration below shows, what data is used to deserialize key and value:
<any-tag>
<key>...</key>
<!-- ~~~ - this data will be used to deserialize a map key -->
<!--^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
</any-tag>
Although value deserializer will have access to the full content of a <key>
node (including the tag name), it will not get much benefits from that,
because tag name will always be fixed for a given map field (equal to a
field name). So, if the field type is an enum
, it cannot select its
variant based on the tag name. If that is needed, then Content
variant
of this enum should be used. Such usage is enabled by annotating a struct
field as “content” field, which implemented as given the field a special
VALUE_KEY
name.