Skip to content

Commit 08171e3

Browse files
committed
seq: Process nested sequences
1 parent c6683a6 commit 08171e3

File tree

1 file changed

+133
-1
lines changed

1 file changed

+133
-1
lines changed

src/de/map.rs

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,8 +623,140 @@ where
623623
DeEvent::Eof => Err(DeError::UnexpectedEof),
624624

625625
// Start(tag), Text, CData
626-
_ => seed.deserialize(&mut *self.map.de).map(Some),
626+
_ => seed
627+
.deserialize(SeqValueDeserializer { map: self.map })
628+
.map(Some),
627629
};
628630
}
629631
}
630632
}
633+
634+
////////////////////////////////////////////////////////////////////////////////////////////////////
635+
636+
/// A deserializer for a value of sequence.
637+
struct SeqValueDeserializer<'de, 'a, 'm, R>
638+
where
639+
R: XmlRead<'de>,
640+
{
641+
/// Access to the map that created this deserializer. Gives access to the
642+
/// context, such as list of fields, that current map known about.
643+
map: &'m mut MapAccess<'de, 'a, R>,
644+
}
645+
646+
impl<'de, 'a, 'm, R> SeqValueDeserializer<'de, 'a, 'm, R>
647+
where
648+
R: XmlRead<'de>,
649+
{
650+
/// Returns a text event, used inside [`deserialize_primitives!()`]
651+
#[inline]
652+
fn next_text(&mut self, unescape: bool) -> Result<BytesCData<'de>, DeError> {
653+
self.map.de.next_text_impl(unescape, true)
654+
}
655+
656+
/// Returns a decoder, used inside [`deserialize_primitives!()`]
657+
#[inline]
658+
fn decoder(&self) -> Decoder {
659+
self.map.de.reader.decoder()
660+
}
661+
}
662+
663+
impl<'de, 'a, 'm, R> de::Deserializer<'de> for SeqValueDeserializer<'de, 'a, 'm, R>
664+
where
665+
R: XmlRead<'de>,
666+
{
667+
type Error = DeError;
668+
669+
deserialize_primitives!(mut);
670+
671+
forward!(deserialize_option);
672+
forward!(deserialize_unit);
673+
forward!(deserialize_unit_struct(name: &'static str));
674+
forward!(deserialize_newtype_struct(name: &'static str));
675+
676+
forward!(deserialize_map);
677+
forward!(deserialize_struct(
678+
name: &'static str,
679+
fields: &'static [&'static str]
680+
));
681+
682+
forward!(deserialize_enum(
683+
name: &'static str,
684+
variants: &'static [&'static str]
685+
));
686+
687+
forward!(deserialize_any);
688+
forward!(deserialize_ignored_any);
689+
690+
/// Representation of tuples the same as [sequences](#method.deserialize_seq).
691+
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, DeError>
692+
where
693+
V: Visitor<'de>,
694+
{
695+
self.deserialize_seq(visitor)
696+
}
697+
698+
/// Representation of named tuples the same as [unnamed tuples](#method.deserialize_tuple).
699+
fn deserialize_tuple_struct<V>(
700+
self,
701+
_name: &'static str,
702+
len: usize,
703+
visitor: V,
704+
) -> Result<V::Value, DeError>
705+
where
706+
V: Visitor<'de>,
707+
{
708+
self.deserialize_tuple(len, visitor)
709+
}
710+
711+
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
712+
where
713+
V: Visitor<'de>,
714+
{
715+
match self.map.de.next()? {
716+
DeEvent::Text(e) => SimpleTypeDeserializer::from_cow(
717+
// Comment to prevent auto-formatting and keep Text and Cdata similar
718+
e.into_inner(),
719+
true,
720+
self.map.de.reader.decoder(),
721+
)
722+
.deserialize_seq(visitor),
723+
DeEvent::CData(e) => SimpleTypeDeserializer::from_cow(
724+
e.into_inner(),
725+
false,
726+
self.map.de.reader.decoder(),
727+
)
728+
.deserialize_seq(visitor),
729+
// This is a sequence element. We cannot treat it as another flatten
730+
// sequence if type will require `deserialize_seq` We instead forward
731+
// it to `xs:simpleType` implementation
732+
DeEvent::Start(e) => {
733+
let value = match self.map.de.next()? {
734+
DeEvent::Text(e) => SimpleTypeDeserializer::from_cow(
735+
e.into_inner(),
736+
true,
737+
self.map.de.reader.decoder(),
738+
)
739+
.deserialize_seq(visitor),
740+
DeEvent::CData(e) => SimpleTypeDeserializer::from_cow(
741+
e.into_inner(),
742+
false,
743+
self.map.de.reader.decoder(),
744+
)
745+
.deserialize_seq(visitor),
746+
e => Err(DeError::Custom(format!("Unsupported event {:?}", e))),
747+
};
748+
// TODO: May be assert that here we expect only matching closing tag?
749+
self.map.de.read_to_end(e.name())?;
750+
value
751+
}
752+
// SAFETY: we use that deserializer only when Start(element), Text,
753+
// or CData event Start(tag), Text, CData was peeked already
754+
_ => unreachable!(),
755+
}
756+
}
757+
758+
#[inline]
759+
fn is_human_readable(&self) -> bool {
760+
self.map.de.is_human_readable()
761+
}
762+
}

0 commit comments

Comments
 (0)