2
2
3
3
use crate :: {
4
4
de:: escape:: EscapedDeserializer ,
5
- de:: { DeEvent , Deserializer , XmlRead , INNER_VALUE , UNFLATTEN_PREFIX } ,
5
+ de:: { deserialize_bool , DeEvent , Deserializer , XmlRead , INNER_VALUE , UNFLATTEN_PREFIX } ,
6
6
errors:: serialize:: DeError ,
7
7
events:: attributes:: IterState ,
8
- events:: BytesStart ,
8
+ events:: { BytesCData , BytesStart } ,
9
+ reader:: Decoder ,
9
10
} ;
10
- use serde:: de:: { self , DeserializeSeed , IntoDeserializer } ;
11
+ use serde:: de:: { self , DeserializeSeed , IntoDeserializer , Visitor } ;
12
+ use serde:: serde_if_integer128;
11
13
use std:: borrow:: Cow ;
12
14
use std:: ops:: Range ;
13
15
@@ -25,11 +27,9 @@ enum ValueSource {
25
27
/// [`next_key_seed()`]: de::MapAccess::next_key_seed
26
28
/// [`next_value_seed()`]: de::MapAccess::next_value_seed
27
29
Unknown ,
28
- /// `next_key_seed` checked the attributes list and find it is not exhausted yet.
29
- /// Next call to the `next_value_seed` will deserialize type from the attribute value
30
+ /// Next value should be deserialized from an attribute value; value is located
31
+ /// at specified span.
30
32
Attribute ( Range < usize > ) ,
31
- /// The same as `Text`
32
- Nested ,
33
33
/// Value should be deserialized from the text content of the XML node, which
34
34
/// represented or by an ordinary text node, or by a CDATA node:
35
35
///
@@ -43,6 +43,96 @@ enum ValueSource {
43
43
/// </any-tag>
44
44
/// ```
45
45
Text ,
46
+ /// Next value should be deserialized from an element with an any name.
47
+ /// Corresponding tag name will always be associated with a field with name
48
+ /// [`INNER_VALUE`].
49
+ ///
50
+ /// That state is set when call to [`peek()`] returns a [`Start`] event
51
+ /// _and_ struct has a field with a special name [`INNER_VALUE`].
52
+ ///
53
+ /// When in this state, next event, returned by [`next()`], will be a [`Start`],
54
+ /// which represents both a key, and a value. Value would be deserialized from
55
+ /// the whole element and how is will be done determined by the value deserializer.
56
+ /// The [`MapAccess`] do not consume any events in that state.
57
+ ///
58
+ /// Because in that state any encountered `<tag>` is mapped to the [`INNER_VALUE`]
59
+ /// field, it is possible to use tag name as an enum discriminator, so `enum`s
60
+ /// can be deserialized from that XMLs:
61
+ ///
62
+ /// ```xml
63
+ /// <any-tag>
64
+ /// <variant1>...</variant1>
65
+ /// <!-- ~~~~~~~~ - this data will determine that this is Enum::variant1 -->
66
+ /// <!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
67
+ /// </any-tag>
68
+ /// ```
69
+ /// ```xml
70
+ /// <any-tag>
71
+ /// <variant2>...</variant2>
72
+ /// <!-- ~~~~~~~~ - this data will determine that this is Enum::variant2 -->
73
+ /// <!--^^^^^^^^^^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
74
+ /// </any-tag>
75
+ /// ```
76
+ ///
77
+ /// both can be deserialized into
78
+ ///
79
+ /// ```ignore
80
+ /// enum Enum {
81
+ /// variant1,
82
+ /// variant2,
83
+ /// }
84
+ /// struct AnyName {
85
+ /// #[serde(rename = "$value")]
86
+ /// field: Enum,
87
+ /// }
88
+ /// ```
89
+ ///
90
+ /// That is possible, because value deserializer have access to the full content
91
+ /// of a `<variant1>...</variant1>` or `<variant2>...</variant2>` node, including
92
+ /// the tag name.
93
+ ///
94
+ /// Currently, processing of that enum variant is fully equivalent to the
95
+ /// processing of a [`Text`] variant. Split of variants made for clarity.
96
+ ///
97
+ /// [`Start`]: DeEvent::Start
98
+ /// [`peek()`]: Deserializer::peek()
99
+ /// [`next()`]: Deserializer::next()
100
+ /// [`Text`]: Self::Text
101
+ Content ,
102
+ /// Next value should be deserialized from an element with a dedicated name.
103
+ ///
104
+ /// That state is set when call to [`peek()`] returns a [`Start`] event, which
105
+ /// [`name()`] represents a field name. That name will be deserialized as a key.
106
+ ///
107
+ /// When in this state, next event, returned by [`next()`], will be a [`Start`],
108
+ /// which represents both a key, and a value. Value would be deserialized from
109
+ /// the whole element and how is will be done determined by the value deserializer.
110
+ /// The [`MapAccess`] do not consume any events in that state.
111
+ ///
112
+ /// An illustration below shows, what data is used to deserialize key and value:
113
+ /// ```xml
114
+ /// <any-tag>
115
+ /// <key>...</key>
116
+ /// <!-- ~~~ - this data will be used to deserialize a map key -->
117
+ /// <!--^^^^^^^^^^^^^^ - this data will be used to deserialize a map value -->
118
+ /// </any-tag>
119
+ /// ```
120
+ ///
121
+ /// Although value deserializer will have access to the full content of a `<key>`
122
+ /// node (including the tag name), it will not get much benefits from that,
123
+ /// because tag name will always be fixed for a given map field (equal to a
124
+ /// field name). So, if the field type is an `enum`, it cannot select its
125
+ /// variant based on the tag name. If that is needed, then [`Content`] variant
126
+ /// of this enum should be used. Such usage is enabled by annotating a struct
127
+ /// field as "content" field, which implemented as given the field a special
128
+ /// [`INNER_VALUE`] name.
129
+ ///
130
+ /// [`Start`]: DeEvent::Start
131
+ /// [`peek()`]: Deserializer::peek()
132
+ /// [`next()`]: Deserializer::next()
133
+ /// [`name()`]: BytesStart::name()
134
+ /// [`Content`]: Self::Content
135
+ Nested ,
46
136
}
47
137
48
138
/// A deserializer for `Attributes`
@@ -141,7 +231,7 @@ where
141
231
// TODO: This should be handled by #[serde(flatten)]
142
232
// See https://github.com/serde-rs/serde/issues/1905
143
233
DeEvent :: Start ( _) if has_value_field => {
144
- self . source = ValueSource :: Text ;
234
+ self . source = ValueSource :: Content ;
145
235
seed. deserialize ( INNER_VALUE . into_deserializer ( ) ) . map ( Some )
146
236
}
147
237
DeEvent :: Start ( e) => {
@@ -189,8 +279,118 @@ where
189
279
true ,
190
280
) )
191
281
}
192
- ValueSource :: Nested | ValueSource :: Text => seed. deserialize ( & mut * self . de ) ,
282
+ // This arm processes the following XML shape:
283
+ // <any-tag>
284
+ // text value
285
+ // </any-tag>
286
+ // The whole map represented by an `<any-tag>` element, the map key
287
+ // is implicit and equals to the `INNER_VALUE` constant, and the value
288
+ // is a `Text` or a `CData` event (the value deserializer will see one
289
+ // of that events)
290
+ ValueSource :: Text => seed. deserialize ( MapValueDeserializer { map : self } ) ,
291
+ // This arm processes the following XML shape:
292
+ // <any-tag>
293
+ // <any>...</any>
294
+ // </any-tag>
295
+ // The whole map represented by an `<any-tag>` element, the map key
296
+ // is implicit and equals to the `INNER_VALUE` constant, and the value
297
+ // is a `Start` event (the value deserializer will see that event)
298
+ ValueSource :: Content => seed. deserialize ( MapValueDeserializer { map : self } ) ,
299
+ // This arm processes the following XML shape:
300
+ // <any-tag>
301
+ // <tag>...</tag>
302
+ // </any-tag>
303
+ // The whole map represented by an `<any-tag>` element, the map key
304
+ // is a `tag`, and the value is a `Start` event (the value deserializer
305
+ // will see that event)
306
+ ValueSource :: Nested => seed. deserialize ( & mut * self . de ) ,
193
307
ValueSource :: Unknown => Err ( DeError :: KeyNotRead ) ,
194
308
}
195
309
}
196
310
}
311
+
312
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
313
+
314
+ macro_rules! forward {
315
+ (
316
+ $deserialize: ident
317
+ $(
318
+ ( $( $name: ident : $type: ty) ,* )
319
+ ) ?
320
+ ) => {
321
+ #[ inline]
322
+ fn $deserialize<V : Visitor <' de>>(
323
+ self ,
324
+ $( $( $name: $type, ) * ) ?
325
+ visitor: V
326
+ ) -> Result <V :: Value , Self :: Error > {
327
+ self . map. de. $deserialize( $( $( $name, ) * ) ? visitor)
328
+ }
329
+ } ;
330
+ }
331
+
332
+ /// A deserializer for a value of map or struct. That deserializer slightly
333
+ /// differently processes events for a primitive types and sequences than
334
+ /// a [`Deserializer`].
335
+ struct MapValueDeserializer < ' de , ' a , ' m , R >
336
+ where
337
+ R : XmlRead < ' de > ,
338
+ {
339
+ /// Access to the map that created this deserializer. Gives access to the
340
+ /// context, such as list of fields, that current map known about.
341
+ map : & ' m mut MapAccess < ' de , ' a , R > ,
342
+ }
343
+
344
+ impl < ' de , ' a , ' m , R > MapValueDeserializer < ' de , ' a , ' m , R >
345
+ where
346
+ R : XmlRead < ' de > ,
347
+ {
348
+ /// Returns a text event, used inside [`deserialize_primitives!()`]
349
+ #[ inline]
350
+ fn next_text ( & mut self , unescape : bool ) -> Result < BytesCData < ' de > , DeError > {
351
+ self . map . de . next_text_impl ( unescape, false )
352
+ }
353
+
354
+ /// Returns a decoder, used inside [`deserialize_primitives!()`]
355
+ #[ inline]
356
+ fn decoder ( & self ) -> Decoder {
357
+ self . map . de . reader . decoder ( )
358
+ }
359
+ }
360
+
361
+ impl < ' de , ' a , ' m , R > de:: Deserializer < ' de > for MapValueDeserializer < ' de , ' a , ' m , R >
362
+ where
363
+ R : XmlRead < ' de > ,
364
+ {
365
+ type Error = DeError ;
366
+
367
+ deserialize_primitives ! ( mut ) ;
368
+
369
+ forward ! ( deserialize_option) ;
370
+ forward ! ( deserialize_unit) ;
371
+ forward ! ( deserialize_unit_struct( name: & ' static str ) ) ;
372
+ forward ! ( deserialize_newtype_struct( name: & ' static str ) ) ;
373
+
374
+ forward ! ( deserialize_seq) ;
375
+ forward ! ( deserialize_tuple( len: usize ) ) ;
376
+ forward ! ( deserialize_tuple_struct( name: & ' static str , len: usize ) ) ;
377
+
378
+ forward ! ( deserialize_map) ;
379
+ forward ! ( deserialize_struct(
380
+ name: & ' static str ,
381
+ fields: & ' static [ & ' static str ]
382
+ ) ) ;
383
+
384
+ forward ! ( deserialize_enum(
385
+ name: & ' static str ,
386
+ variants: & ' static [ & ' static str ]
387
+ ) ) ;
388
+
389
+ forward ! ( deserialize_any) ;
390
+ forward ! ( deserialize_ignored_any) ;
391
+
392
+ #[ inline]
393
+ fn is_human_readable ( & self ) -> bool {
394
+ self . map . de . is_human_readable ( )
395
+ }
396
+ }
0 commit comments