in serde-reflection/src/de.rs [394:443]
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
self.format.unify(Format::TypeName(name.into()))?;
// Pre-update the registry.
self.tracer
.registry
.entry(name.to_string())
.unify(ContainerFormat::Enum(BTreeMap::new()))?;
let known_variants = match self.tracer.registry.get_mut(name) {
Some(ContainerFormat::Enum(x)) => x,
_ => unreachable!(),
};
// If we have found all the variants OR if the enum is marked as
// incomplete already, pick the first index.
let index = if known_variants.len() == variants.len()
|| self.tracer.incomplete_enums.contains(name)
{
0
} else {
let mut index = known_variants.len() as u32;
// Scan the range 0..=known_variants.len() downwards to find the next
// variant index to explore.
while known_variants.contains_key(&index) {
index -= 1;
}
index
};
let variant = known_variants.entry(index).or_insert_with(|| Named {
name: (*variants
.get(index as usize)
.expect("variant indexes must be a non-empty range 0..variants.len()"))
.to_string(),
value: VariantFormat::unknown(),
});
let mut value = variant.value.clone();
// Mark the enum as incomplete if this was not the last variant to explore.
if known_variants.len() != variants.len() {
self.tracer.incomplete_enums.insert(name.into());
}
// Compute the format for this variant.
let inner = EnumDeserializer::new(self.tracer, self.samples, index, &mut value);
visitor.visit_enum(inner)
}